Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Embedded Systems EEL4740C Lab
FPGA Powered Relay Controller Targeting the Xilinx Spartan-3A FPGA (XC3S200A-4VQG100C)
Final Project Report
Anthony Nuñez PID: 4614872
Final Project Proposal: FPGA Powered Relay Controller
Justification
The main objective of this project is enable the control of multiple relays via an FPGA while also
communicating with a computer via serial communications in order to update a user via the computer as to what
is the state of each relay.
This project is part of a larger research project which I am conducting. The research aims to test the potential
implementations of an FPGA into IoT (Internet of Things) applications. The specifications of this project aims
to test the abilities of such an implementation to drive a control system while providing necessary data for the
analysis of operations via cloud computing.
Objectives
Receive an 8-bit wide vector input from switches
Store the state of each switch in an 8-bit wide register
Control 8 relays by turning them on or off based on the signal received from the switches
Report to the computer via the serial interface, displaying the current state of the 8 relays as well as the
incoming signals from the remote
Background
The Internet of Things (IoT) has been a technological phenomenon brought on by the power of smaller, more
powerful computing devices becoming able to connect to the internet or form a network amongst each other. [1]
This began with the advent of the Arduino development platform and its wide spread popularity amongst
electronics hobbyist due to its ease of use and capacity for rapid prototyping thanks to lightweight APIs and
widely usable drivers and Arduino IDE. [2] With wide spread use of the Arduino across the hobbyist
community, the implementation of control and data acquisition systems became interconnected with the
internet. The ability to control systems via the internet and to acquire and transport data after collecting it from a
prototype catapulted this technology into the spotlight.
The Raspberry Pi aimed to expand the capabilities of microcontrollers by taking a step up, using an ARM based
processor and bringing a full-featured computer down to the size of a wallet. The power of the Raspberry Pi
came in the fact that besides being a full-fledged computer, it also had access to GPIO and other modules such
as I2C, SPI, UART, USB, Ethernet, and Wi-Fi. This meant that the Raspberry Pi could do so much more than
the Arduino while maintaining its computing capabilities. [3]
However, the Raspberry Pi and Arduino, though both equally popular and capable, suffer from fundamental
flaws in their implementation. Both devices implement solutions in software, meaning that their operating
speeds are slower than bare-metal implementations such as integrated chips designed specifically for a given
purpose. Unlike them, a Field Programmable Gate Array (FPGA) assumes the physical design of a solution
which allows rapid operating speeds unlike anything a Raspberry Pi or Arduino could manage. Additionally,
FPGAs are cheap and feature an extensive amount of IO unlike microcontrollers. As a matter of fact, if you
need a certain device or feature, you can implement it yourself or use the Intellectual Properties (IPs) of the
manufacturer. This gives you immense control over what your system does. [4]
Brainstorming & Solution Analysis
There are not many solutions as to how to solve this problem. All we really need to solve the problem, at a
functional level, is the array of 7 switches, a load and reset button, and the UART transmission line for
communication with the Raspberry Pi (which I am using as my ‘computer’). The inclusion of a register allows
for the prevention of any issues inputting the switch states into the components which use it such as the relay
inputs and the UART transmitter input.
Figure 1: Level 0 Functional Diagram of the Relay Controller
Figure 2: Level 1 Functional Diagram of the Relay Controller
Design Specification
System Clock
Input Frequency: 50 MHz (crystal oscillator)
Prescaled Frequency (Debounce Module): 763 Hz (1.3 ms period /w 50% duty cycle)
UART Frequency (UART Transmitter): 9600 Hz (50% duty cycle)
Debounce Module
Check Period: 10 ms
Method: Vector-based (8-bit check)
Clock: External (Prescaled)
Register
Size: 8 bits
System input width: 8-bit
System output width: 8-bit
UART Transmitter
Start Bits: One
Stop Bits: One
Payload: 8 bits
Parity Bits: None
Baud rate: 9600 baud
Figure 3: Relay Controller Operations Flowchart
Input
• Switches are flipped on or off (SWITCH_IN signal)
• LOAD button is pressed
Processing
• Both prescalers prescale the 50 MHz clock signal and provide it to their respective modules
• LOAD button signal is debounced
• Debounced LOAD signal triggers the register to load the signal and then triggers the UART transmitter to send out the UART message carrying the 8 switch states
• Register outputs the 8 switch states and provides the states to the UART transmitter
• UART packages up the data for transmission
Output
• 8 signal lines are available from the system for connecting to the relay via GPIO Pins 29 down to 22 (RELAY_SIG)
• UART transmission is available via the single UART_TX line Direct GPIO pin 0
Materials & Costs
Quantity Name Cost
1 Micro Nova’s Mercury DIP FPGA board
(Xilinx Spartan-3A) $79.00
1 Micro Nova’s Mercury Baseboard $29.00
1 Cana Kit’s Raspberry Pi 3 Complete Starter Kit $74.99
1 SunFounder’s 8 Channel 5V Relay $11.99
Methodology & Design
Prescaler
The prescaler for the debounce module uses an interesting method as proposed by Nick Williams in his
YouTube tutorial series on FPGAs. The way this works is by finding a division value which comes close to the
necessary one but is a power of 2. As a result, you can use a trick with binary numbers where the most
significant bit, in this case bit 15, is only 1 half of the time. As a result, you can assign its value as the output
clock signal which will naturally oscillate at the necessary frequency. [5]
UART Prescaler
The prescaler for the UART module has a more conventional method of adjusting. Using a counter, we can
invert the clock signal every time the counter reaches the maximum value which happens to be half of the
prescaler value necessary to get the frequency desired.
Debounce Module
The debounce module works by sampling the LOAD button signal once every millisecond and shifting all the
values in an intermediate 8-bit vector before appending this sampled value. Once all 8 bits in the vector are ones
and do not contain any zeroes (meaning the signal is clean and debounced) we output a one on the output of the
module.
8-bit Register
The 8-bit register works on the simple principle of a process bound to the input clock which only assigns a
value to a given signal when the rising edge of the clock is trigger and the LOAD button is pressed. The output
of the register is always the last value to have been loaded but never the current value on the input if the LOAD
button has not been pressed.
UART Transmission Module
The only element which requires the design of a finite state machine was the UART transmission module as the
implementation of serial communications is not inherently intuitive. The IDLE state is the state in which the
system sits when no messages are to be sent, keeping the transmission line high as required by the transmission
protocol. When the SEND button is pressed, the system moves to another idling state, BTN, which prevents the
system from sending many messages in the milliseconds it is pressed down and does not allow transmission
until the SEND button is released. Once released, the system moves into the TX state which packages up the
payload including the start and stop bits with the 8 data bits in between before iterating through each bit and
sending them out onto the transmission line by looping within itself until the iterator reaches 0.
VHDL Top Level Module
VHDL features the amazing capability to establish a “top level” module which instantiates other modules as
components which can be interconnected with each other and the IO of the top level itself. One can, for
example, instantiate two instances of the debounce module if one has two buttons which need their signal
cleaned up.
Figure 5: Instantiation of an instance of the UART_TX_Module
Using the UART transmission module as an example, it can be seen that all the IO of the module is present and
we provide this piece of syntax with signals or top level inputs in order to help connect it to the top level outputs
or the other modules via signals.
INIT
IDLE
TX
BTN
DATA = X”00” TX = ‘1’
SEND’ SEND
SEND
SEND’
s_index != 0
s_dataOut = ‘0’ & DATA & ‘1’
s_tx = s_dataOut(s_index) s_index = s_index – 1
IF s_index = 0
state <= init
s_tx = ‘1’
Inputs: DATA, SEND
Outputs: s_tx
Figure 4: UART Transmission Module Finite State Machine
Raspberry Pi’s Python Script
Figure 6: Python Script for Reading and Formatting the UART Transmission
The script is very practical and straight forward. The infinite loop reads from the serial interface, storing the
byte of data into a variable before formatting into binary and then reversing the string into its proper order.
After that, a FOR loop traverses through the 8 bits and formats the output to give whether or not the channel is
ON or OFF. Finally, the current time is stored into a variable and we post to the screen the current status of the
channels as well as at what time the change occurred.
Analysis of Tests and Results
Test Bench (Xilinx’s ISIM)
Test Bench Stimuli
Figure 7: VHDL Test Bench Stimuli for Testing the Relay Controller Top Level Module
In designing the stimulus for the test bench, there were some important
points to keep in mind. This includes the understanding how mechanical
switches work.
Upon pressing down a button, such as in the case of the LOAD button, a
clean, square signal does not instantly appear. There is a time when the
button bounces upon being pressed down or released which causes the
signal to oscillate rapidly between its ON and OFF states (see Figure 7).
To be on the safe side, the average time of instability is approximately 10
milliseconds, give or take. As a result, it was important to set the wait time
for the LOAD button to 10 milliseconds both in the ON state as well as the OFF state, in order to assure the
debounce module would generate the proper internal signal for the LOAD button (See lines 102, 103, 110, and
111 in Figure 6).
Figure 8: Simplified Mechanical
Switch Waveform [7]
Test Bench Waveform
Figure 9: Overview of the VHDL Test Bench Waveform for the Relay Controller Top Level Module
Upon looking at the waveform (as seen above in Figure 8), we can see that the system works according to
specification and meets the objectives as set for the project. However, in order to better analyze the results of
this test bench, we will take a closer look at each individual component at play here.
Switching and Loading the Register
Figure 10: Closer Look at the Switching and Loading Mechanism of the Register
As can be seen, the stimuli begins with LOAD going high for 10 milliseconds then going low for 10
milliseconds which gives the debounce module the length of stimuli necessary to trigger its internal state change
which in turn triggers the load on the register which causes the RELAY_SIG to change to the first SWITCH_IN
value of 0xF0. After 5 milliseconds, the next round of 10 millisecond LOAD signals begins which causes the
RELAY_SIG to change to 0xAC when the register catches the clean, debounced LOAD signal.
UART Transmission Module
Figure 11: Closer Look at the UART Transmission Module’s Transmission of the 0xF0 state of the switches (between
blue cursors; start bit up to the start of the stop bit)
The UART module is programmed to withhold the message transmission until the LOAD button has been
released to avoid the potential of many messages being sent while the LOAD signal is HIGH. As a result, it is
not until the end of the LOAD signals LOW state being debounced that the UART transmission module reacts
and actually sends out the UART message containing the states of the switches as provided by the register. This
can be seen between the blue lines, starting with the LOW start bit, 4 HIGH bits and 4 LOW bits to signify
0xF0 before going HIGH again with the stop bit and the idle HIGH signal.
Real-World Implementation
Figure 12: Physical Implementation of the System (Raspberry Pi, Spartan-3A, and Relay)
As can be seen above, we have the Raspberry Pi 3 on the left which has its GPIO Pin 15 (UART RX) hooked up
to the Direct GPIO Pin 0 on the Mercury Board while the respective wires are hooked up to the relay including
3.3 V and GND (5V Tolerant GPIO Pins 29 to 22 for the relay channels)
Figure 13: Relay Controller in its Default State (0x00)
Above (Figure 13) shows the relay controller in its default state (0x00). We note that the relay is designed such
that when the signal to the inputs is HIGH, the relay opens (OFF), and if LOW, the relay closes (ON). As a
result, all switches are technically on by default but we consider this the OFF state for the sake of convenience.
Figure 14: Console Output of the Python Script
In Figure 14, we can see the output of the default state (when loaded) as well as the two states used to show the
implementation which are the two states we used for the test bench. During the presentation demonstration,
more states will be shown. Below are the pictures of the device itself showing the two states (0xF0 and 0xAC in
that respective order).
Figure 15: Relay Controller in State 0xF0
Figure 16: Relay Controller in State 0xAC
Conclusions
Through the use of an FPGA development platform and base application of fundamental embedded system
design knowledge and practical skills, it is possible to implement a hybrid FPGA/Microcontroller based control
system with intercommunication capabilities. This helps assist in the collection of system state data for use in
analysis or larger scale control implementations. Through this design implementation, it was possible to
interface a Xilinx Spartan-3A FPGA with a Raspberry Pi 3 over unidirectional UART communications,
allowing the FPGA to concern itself with the operation of the input processing and control of the peripheral
(relay) while updating the Raspberry Pi of the states of said peripheral in order to potentially add this
information to a database or update a user via a mobile app interface (such as on an Android or iPhone).
Future Work
Future work on this topic is currently being conducted by myself as a research project for the McNair
Undergraduate Research Fellowship. The system will be expanded to allow for the storage of state changes in
the form of a CSV file (Comma Separated Values file) which could easily be expanded to accommodate such
things as the cloud (Amazon AWS for example). I will be implementing other systems by themselves as well as
in parallel to show the capabilities of such an interfaced system to implement expansive control and data
acquisition systems side by side.
References
[1] G. Press, "A Very Short History of the Internet of Things," 18 June 2014. [Online]. Available:
http://www.forbes.com/sites/gilpress/2014/06/18/a-very-short-history-of-the-internet-of-
things/#6326f86c2df5. [Accessed 1 August 2016].
[2] P. Torrone, "Why the Arduino Won and Why It's Here to Stay," 2011 February 2011. [Online]. Available:
http://makezine.com/2011/02/10/why-the-arduino-won-and-why-its-here-to-stay/. [Accessed 1 August
2016].
[3] Raspberry Pi Foundation, "Raspberry Pi Documentation," Raspberry Pi Foundation, [Online]. Available:
https://www.raspberrypi.org/documentation/. [Accessed 1 August 2016].
[4] F. Vahid and T. Givargis, Embedded System Design: A Unified Hardware/Software Introduction, New
York, NY: John Wiley & Sons, Inc., 2002.
[5] B. C. Readler, VHDL By Example, Middletown, DE: Full Arc Press, 2015.
[6] N. Williams, "FPGAs; Lesson 2: Interconnecting VHDL modules; Top Level Design and much more," 10
February 2015. [Online]. Available: https://www.youtube.com/watch?v=uhxTgUSZvYE. [Accessed 2
August 2016].