Difference between revisions of "S13: Smart Cube"
(→Software Implementation) |
(→Grading Criteria) |
||
(24 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Smart CUBE == | == Smart CUBE == | ||
Line 19: | Line 7: | ||
== Objectives & Introduction == | == Objectives & Introduction == | ||
+ | The main purpose of this project is to interface between the LPC1758 development board and the RN-XV WiFly wifi module and between the LPC1758 and the 8x8 RGB LED matrix. The interface between LPC1758 and the wifi module is the Front-End and the interface between the LPC1758 and the LED matrix is the Back-End of the project. In most parts of the project, the LPC1758 will take the input from the Front-End interface and output the results on the Back-End interface. Only the current time is taken from the RTC clock. | ||
+ | |||
+ | The objectives of this project are: | ||
+ | *RGB LED matrix displays the current time when the system is in idle mode | ||
+ | *Real time OS collects and transfers data over RN-XV WiFly | ||
+ | **Notify the user when there is a service such as email or alarm | ||
+ | **Set alarm trigger using a web server or a mobile app. | ||
+ | **Output alarm signal on the LED matrix when the alarm trigger is on | ||
+ | **Buzzer will be on when the alarm trigger is on | ||
+ | **Get an email notification when there is an incoming email | ||
+ | **Get the weather (current temperature at any city)and display it on the LED matrix | ||
+ | |||
+ | |||
=== Team Members & Responsibilities === | === Team Members & Responsibilities === | ||
Line 67: | Line 68: | ||
**Set Alarm | **Set Alarm | ||
**Send Weather (temp) | **Send Weather (temp) | ||
+ | **Setting Email | ||
*Interface LPC1758 board with the LED matrix | *Interface LPC1758 board with the LED matrix | ||
</td> | </td> | ||
<td> | <td> | ||
+ | * Successful | ||
* Successful | * Successful | ||
* Successful | * Successful | ||
Line 84: | Line 87: | ||
**Alarm | **Alarm | ||
**Weather | **Weather | ||
+ | **Email | ||
</td> | </td> | ||
<td> | <td> | ||
+ | *Successful | ||
*Successful | *Successful | ||
*Successful | *Successful | ||
Line 100: | Line 105: | ||
* Connect UI to Functions | * Connect UI to Functions | ||
* Buzzer interface | * Buzzer interface | ||
+ | * Acceleration sensor used for turning off the alarm | ||
* Combine software and hardware tasks | * Combine software and hardware tasks | ||
</td> | </td> | ||
<td> | <td> | ||
+ | * Successful | ||
* Successful | * Successful | ||
* Successful | * Successful | ||
Line 117: | Line 124: | ||
</td> | </td> | ||
<td> | <td> | ||
− | * | + | * Successful |
− | * </td> | + | * Successful </td> |
</tr> | </tr> | ||
Line 254: | Line 261: | ||
*Buzzer | *Buzzer | ||
*Wifly Module | *Wifly Module | ||
+ | *Battery Pack | ||
====LPC1758 Development Board==== | ====LPC1758 Development Board==== | ||
Line 291: | Line 299: | ||
[[File:CmpE146_S13_T2_HWDesign0.4.png|center|frame]] | [[File:CmpE146_S13_T2_HWDesign0.4.png|center|frame]] | ||
<div style="text-align: center;">'''Figure 0.4:''' Wifly Module </div> | <div style="text-align: center;">'''Figure 0.4:''' Wifly Module </div> | ||
+ | |||
+ | ====Battery Pack==== | ||
+ | [[File:CmpE146_S13_T2_HWDesign0.5.png|center|frame]] | ||
+ | <div style="text-align: center;">'''Figure 0.5:''' Battery Pack </div> | ||
==== System Building Block==== | ==== System Building Block==== | ||
Line 396: | Line 408: | ||
[[File:CmpE146_S13_T2_SWDesign1.png|center|frame]] | [[File:CmpE146_S13_T2_SWDesign1.png|center|frame]] | ||
− | <div style="text-align: center;">'''Figure | + | <div style="text-align: center;">'''Figure 3:''' Data Task </div> |
Line 402: | Line 414: | ||
[[File:CmpE146_S13_T2_SWDesign2.png|center|frame]] | [[File:CmpE146_S13_T2_SWDesign2.png|center|frame]] | ||
− | <div style="text-align: center;">'''Figure | + | <div style="text-align: center;">'''Figure 4:''' Service Task </div> |
Line 409: | Line 421: | ||
[[File:CmpE146_S13_T2_SWDesign3.png|center|frame]] | [[File:CmpE146_S13_T2_SWDesign3.png|center|frame]] | ||
− | <div style="text-align: center;">'''Figure | + | <div style="text-align: center;">'''Figure 5:''' Terminal Task</div> |
The main purpose of the LED display task is to output data such as time, email, email count, weather, and alarm on the LED matrix. This task has the highest priority among all the tasks. If no task requires service, this task will display the real-time clock on the LED matrix. If other task requires service, it will output that service. For instance, LED display task will output alarm icon on LED matrix when the alarm trigger is set. | The main purpose of the LED display task is to output data such as time, email, email count, weather, and alarm on the LED matrix. This task has the highest priority among all the tasks. If no task requires service, this task will display the real-time clock on the LED matrix. If other task requires service, it will output that service. For instance, LED display task will output alarm icon on LED matrix when the alarm trigger is set. | ||
[[File:CmpE146_S13_T2_SWDesign4.0.png|center|frame]] | [[File:CmpE146_S13_T2_SWDesign4.0.png|center|frame]] | ||
− | <div style="text-align: center;">'''Figure | + | <div style="text-align: center;">'''Figure 6:''' LED display Task</div> |
=== Hardware Implementation === | === Hardware Implementation === | ||
Line 491: | Line 503: | ||
====Acceleration Sensor==== | ====Acceleration Sensor==== | ||
[[File:CmpE146_S13_T2_HWDesign7.png|center|frame]] | [[File:CmpE146_S13_T2_HWDesign7.png|center|frame]] | ||
− | <div style="text-align: center;">Figure: Acceleration Sensor </div> | + | <div style="text-align: center;">Figure 7: Acceleration Sensor </div> |
This is an on-board sensor as show above (or show on the LPC1758 development board). The use of this sensor in the project is as a trigger to turn off the alarm. It is used to get the current locations of x and y and compare these values with the previous locations of x and y of the cube. The functions for this acceleration sensor are included in "acceleration_sensor.hpp" file. Below is how to use the sensor. It is in the "io_source.cpp" file. | This is an on-board sensor as show above (or show on the LPC1758 development board). The use of this sensor in the project is as a trigger to turn off the alarm. It is used to get the current locations of x and y and compare these values with the previous locations of x and y of the cube. The functions for this acceleration sensor are included in "acceleration_sensor.hpp" file. Below is how to use the sensor. It is in the "io_source.cpp" file. | ||
Line 525: | Line 537: | ||
} | } | ||
</pre> | </pre> | ||
+ | |||
====WiFly==== | ====WiFly==== | ||
The management of the Wi-Fly and wifi connectivity was done in the services task. This task was responsible for initializing the Wi-Fly with the appropriate values and connecting to the defined SSID. With the Wi-Fly connected to a SSID it was the service task responsibility to ensure that a connection was established and maintained. With a connection obtained the Wi-fly module could access the smart cube website and receive data as a tcp client and server. | The management of the Wi-Fly and wifi connectivity was done in the services task. This task was responsible for initializing the Wi-Fly with the appropriate values and connecting to the defined SSID. With the Wi-Fly connected to a SSID it was the service task responsibility to ensure that a connection was established and maintained. With a connection obtained the Wi-fly module could access the smart cube website and receive data as a tcp client and server. | ||
Line 738: | Line 751: | ||
== Testing & Technical Challenges == | == Testing & Technical Challenges == | ||
+ | ===Testing=== | ||
+ | The primary tools we used were for testing was Hercules, the debugging potential and testing with Hercules are endless. Hercules allows for testing of not only the usb uart0 communication, but it allows for debugging a tcp client or server. Using Hercules we were able to test our PHP server functions, buy acting as a client and making a request to the PHP server. As well we were able to test the weather api. The process of testing the PHP server function from Hercules is as follows: | ||
+ | 1. At the TCP client tab | ||
+ | a. Input the server IP | ||
+ | b. Input the server port (if a php request, use 80) | ||
+ | 2. Click connect | ||
+ | a. Result should be “Connected to IPADDRESS | ||
+ | 3. In the input box type | ||
+ | a. GET “IPADDRESS/myfunctions.php \n\n\r\n | ||
+ | 4. The output should be the result of the executed PHP file. | ||
+ | |||
+ | ====Test Cases==== | ||
+ | The execution of test cases was done manually, and the results were then verified with the expected output. | ||
+ | |||
+ | =====Alarm===== | ||
+ | *Set the Alarm | ||
+ | *Set the Alarm more than once | ||
+ | *Clear the Alarm | ||
+ | *Clear the Alarm while Triggered | ||
+ | *Set the Alarm while Triggered | ||
+ | |||
+ | =====Weather===== | ||
+ | *Set the Weather City | ||
+ | *Get Weather without Internet connectivity | ||
+ | |||
+ | =====Email===== | ||
+ | *Set the email | ||
+ | *Set the Password | ||
+ | *Get the Email count | ||
+ | *Get the Email Count without Internet connectivity | ||
+ | |||
+ | |||
+ | ===Technical Challenges=== | ||
During the implementation of the smart cube, we encountered numerous testing and technical challenges. These challenges ranged from the implementation of the 8x8 led matrix to the interfacing of the web server to the development board. | During the implementation of the smart cube, we encountered numerous testing and technical challenges. These challenges ranged from the implementation of the 8x8 led matrix to the interfacing of the web server to the development board. | ||
+ | ====RGB LED matrix implementation==== | ||
+ | There were multiple issues encountered during the implementation of the LED matrix such as the use of shift registers, the output of a number or a character, and SPI communication. | ||
+ | ====Shift Register==== | ||
+ | This was the first problem encountered when implementing and testing the spi communication between the CPU and the shift register. A shift register 74HC595 has to two parts, one is an 8-stage shift register and one is an 8-bit storage register. The problem was to get the data from the 8-stage shift register and store to the 8-bit storage register because the misuse of the shift register clock input (SHCP) and the storage register clock input (STCP). We got wrong data all the time because we did not synchronize the two signals with the clock input from the LPC1758. The problem was solved after we connected the two signals with the clock input. | ||
+ | |||
+ | ====SPI Exchange==== | ||
+ | This was the second major problem during when using SPI to exchange or transfer data. It is still unclear that the first spi-sent byte is not always captured correctly by the shift register. For instance, when we use "spi1_Exchange3Bytes(char data)" to send data to all 3 shift registers (Green LEDs, Blue LEDs, and Red LEDs are controlled by first,second, and third shift registers respectively ), the first sent byte will be shifted to the third register, the second byte is shifted to the second registers, and the last byte will stay at the first register. The data is captured correctly at the first and second register, but not captured correctly at the third register. | ||
− | === Web Server Multiple Commands Issue === | + | The first approach to this problem was to delay the output control signal of the shift register for some Milli-seconds or micro seconds because we thought that the CPU speed was running so fast causing the first sent byte not captured correctly. However, this approach did not work. |
+ | |||
+ | The second approach was to send one more byte to the shift register. This means instead of sending three bytes to shift registers, the CPU then sent 4 bytes. Finally, this approach fixed the problem. This might not be a good approach at the engineering level, but it solved our problem. | ||
+ | |||
+ | ====Output a digit or a character==== | ||
+ | This problem involved with timing analysis and how to manage the outputs correctly. A digit, for instance, has to be output in 3 rows and columns (depending on the height of the digit). To output a digit on the LED matrix, we first sent a byte of data using spi communication to the columns for a digit, then turn on the first row for a small period of time such as one millisecond. Then, we continued the same step for the second row and third row for that digit. However, the whole process happened very quickly that we just saw a flashing digit on the LED matrix. To solve this problem, we want this process to be repeated for a number of time, so we could see the digit clearly. A "for" loop was used to repeat and output a digit. | ||
+ | |||
+ | Note: Rows and column are used corresponding to the LED matrix schematic. | ||
+ | |||
+ | ====Web Server Multiple Commands Issue ==== | ||
During our implementation of the Web server we were encountering a very strange error. This error occurred when two commands would be sent consecutively from the web server. An example of this was: | During our implementation of the Web server we were encountering a very strange error. This error occurred when two commands would be sent consecutively from the web server. An example of this was: | ||
<pre> | <pre> | ||
Line 768: | Line 830: | ||
== Conclusion == | == Conclusion == | ||
− | + | ||
+ | In this project, we have successfully finished our goals and tasks such as interfaces that allow the user to select the desirable functions of the cube: alarm setting, weather location, and RTC clock. We are able to perform these tasks and demo them precisely. Also, we added some more features to our Smart Cube such as email notification, moving the cube to turn off the alarm as it was planned to use a switch, as well as selecting different melody or ringtones for alarm sound. | ||
+ | |||
+ | There were a number of problems encountered during the hardware implementation such as the use of shift registers, the output of a number or a character, and SPI communication. It took a while to figure what caused which problem, then we were able to have different approaches to solve the problem as discussed in the testing and technical challenges section. | ||
+ | |||
+ | This project have shown a large concept of how an Embedded System as well as all the interfaces between the CPU and I/0 devices. We were able to manage between software and hardware and understand the relationship between them such as using FreeRTOS to communicate and perform different tasks with different levels of priority. | ||
=== Project Video === | === Project Video === | ||
Line 782: | Line 849: | ||
=== References Used === | === References Used === | ||
− | + | [1] How to build a 8x8 RGB LED Matrix with PWM using Adruino *[http://francisshanahan.com/index.php/2009/how-to-build-a-8x8x3-led-matrix-with-pwm-using-an-arduino/] | |
+ | |||
+ | [2] 8x8 RGB LED matrix | ||
+ | |||
+ | [3] 74HC595 Shift Register datasheet | ||
+ | |||
+ | [4] RN-XV Wifly wifi module | ||
=== Appendix === | === Appendix === | ||
You can list the references you used. | You can list the references you used. |
Latest revision as of 21:07, 23 May 2013
Contents
- 1 Smart CUBE
- 2 Abstract
- 3 Objectives & Introduction
- 4 Parts List & Costs
- 5 Design & Implementation
- 6 Testing & Technical Challenges
- 7 Conclusion
- 8 References
Smart CUBE
Abstract
The Smart Cube is an 8x8 RGB LED clock, that provides the user with the weather, email count, and a programmable alarm. The Smart Cube can be accessed via its local Website and its Windows Phone 8 mobile application. From the website and mobile app the user can set the alarm, set the alarm melody, set the city to get the weather, define the email credentials, and set other functional features. The 8x8 RGB LED clock allows for the information to be displayed in any color, and dynamic.
With the current functionality in place, the possibilities for upgrading the smart cube are endless!
Objectives & Introduction
The main purpose of this project is to interface between the LPC1758 development board and the RN-XV WiFly wifi module and between the LPC1758 and the 8x8 RGB LED matrix. The interface between LPC1758 and the wifi module is the Front-End and the interface between the LPC1758 and the LED matrix is the Back-End of the project. In most parts of the project, the LPC1758 will take the input from the Front-End interface and output the results on the Back-End interface. Only the current time is taken from the RTC clock.
The objectives of this project are:
- RGB LED matrix displays the current time when the system is in idle mode
- Real time OS collects and transfers data over RN-XV WiFly
- Notify the user when there is a service such as email or alarm
- Set alarm trigger using a web server or a mobile app.
- Output alarm signal on the LED matrix when the alarm trigger is on
- Buzzer will be on when the alarm trigger is on
- Get an email notification when there is an incoming email
- Get the weather (current temperature at any city)and display it on the LED matrix
Team Members & Responsibilities
- Phuoc Tran
- Interface LPC1758 with 8x8 RGB LED matrix using shift registers, buzzer interface using PWM signal, and acceleration sensor.
- Christopher Harris
- Interface LPC1758 with WiFly module, server to WiFly communication, Website UI, and Windows 8 mobile app.
Week | Planned Tasks | Achievement |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Parts List & Costs
Item | Details | Source | Cost Ea. | Qty. | Total |
---|---|---|---|---|---|
MicroController | LPC 1758 SJSU Dev Board | Preet | $60.00 | x1 | $60.00 |
Wifi Module | RN-XV Wifly | Sparkfun | $37.99 | x1 | $37.99 |
RGB LED Display | 8x8 RGB LED Matrix | Ebay | $5.99 | x1 | $5.99 |
Shift Register | SN74HC595 | Sparkfun | $0.23 | x3 | $.69 |
Wire | Female -> Female Jumper wire | Sparkfun | $0.28 | x50 | 14.39 |
Wire | 30 Gauge Wrapping wire | Anchor | $5.00 | x1 | $5.00 |
Prototyping board | 6"x6" Perforated Prototyping board | Radio Shack | $6.99 | x1 | $6.99 |
IC Socket | Socket IC 16 Pin | Anchor | $.37 | x6 | $2.25 |
Resistors | 220 Ohm 1/4 Resistor | Anchor | $.06 | x32 | $1.92 |
Linux Server | Raspberry Pi | Ebay | $35.00 | x1 | $35.00 |
Wireless Router | Ti Link 703N Mini Router | Frys | $24.00 | x1 | $24.00 |
Buzzer | Unknown | From Preet | x1 | ||
Battery Pack | From previous project | x1 |
Design & Implementation
Hardware Design
The main hardware components used in this project include:
- LPC1758 Development Board
- 8x8 RGB LED matrix
- 74HC595 Shift Register
- Buzzer
- Wifly Module
- Battery Pack
LPC1758 Development Board
It is the CPU of the project. It communicates with devices or transfers communications between devices to perform tasks. The LPC1758 dev board is running under SJSU development software package. The package contains most of drivers necessary for the CPU to communicate with devices such as SPI interface, PWM motor controller.
8x8 RGB LED matrix
The figure below is the schematic of an 8x8 RGB LED matrix. It has the size of 60 mm square, and it contains 8 anode terminals and 24 cathode terminals in a total of 192 LEDs. 64 of the LEDs are red, 64 are Green, and the other 64 are Blue. The purpose and use of this LED matrix is very important in this cube because it is the main output of the project. It will display the real time time clock, alarm and email notifications, and temperature.
74HC595 Shift Register
The purpose of the shift register in this project to take the serial inputs from the CPU and convert to both parallel outputs and serial outputs. Parallel outputs is use to turn on and off the LEDs. Serial outputs is used to feed into another shift register if applicable.
Buzzer
A buzzer is used for alarm of email notifications. It will sound to notify that the alarm is on or someone just got a mail.
Wifly Wifi Module RN-XV
(As discussed in the software implementation section)
Note that this wifi module is listed here because it's a hardware component; however, its implementation is on the software side. It's connected to the XBee port on the LPC board.
Battery Pack
System Building Block
Figure 1 shows the block diagram of the whole circuit. It shows the basic idea of how all the devices or part are connected as well as their inputs and outputs.
System Schematic Among CPU, Shift Registers, and LED matrix
Figure 2 demonstrates more detail of circuit implementation. The circuit was built and tested on Logic Works. It shows the interface among the LPC board, LED matrix, and 3 shift registers. The red, green, and blue LEDs represents the corresponding ones of the RGB LED matrix. All Px.x pins (outputs), CLK, and MOSI are generated from the LPC 1758 board. The binary switches are used to test the behavior of the circuit when switching the output pins from high to low or vice versa.
Hardware Interface
SPI Interface
In the SPI interface figure, CLK is pin P0.7, MOSI is pin P0.9, and CS0,CS1,CS2 are P0.15,P1.30, and P1.31. CLK is the output from LPC1758 to shift registers. Master Out Slave In (MOSI) is used to send serial data (one Byte at a time) to the first shift register along with clk. Serial outputs from the first register will feed to the next register and so on. CS0, CS1, CS2 are used to control parallel outputs of shift registers.
Below is the figure of how to initialize and set SPI driver for SSP1
An "spi.h" header file is used for SSP1 driver.
Because peripheral clk (PCLK) is a high speed clock(48Mhz), we need to slow it down so that SPI devices such shift registers can operate efficiently. The SPI clock speed equation is PCLK / (CPSDVSR × [SCR+1]) with PCLK being 48Mhz.
"LPC_SSP1->CPSR = 254" is to set CPSDVSR equal to 254 since CPSDVSR is an 8-bit register. "LPC_SSP1->CR0 |= (1 << 9)" is to set SCR bits to 1(default is 0). The last two lines in the SPI setting are used for clock polarity (CPOL) and clock phase (CPHA). The setting of CPOL and CPHA depends on the design of SPI devices.
To send data to shift register and output data, a function "spi1_ExchangeByte(data)" in "spi.h" is call where data size is one byte. After the first call, a byte of data will be sent to the first shift register.If the CPU continues to send data, each byte of data will be shift to the next register and so on. It the CPU stops sending data, the last bytes, depending on number of shift register used, will be held at the outputs of these shift registers. Now, the CPU will generate control signals to output these data.
Buzzer Interface
The buzzer interface is quite simple since the diver for PWM1 is already given in "lpc_pwm.hpp" and "lpc_pwm.cpp" as declared below
#include "lpc_pwm.hpp" #include "lpc_pwm.cpp"
To initialize and use P1.20 as a PWM signal where pwm2 is P1.20 and 1000 is initialized as the PWM frequency
//initialize PWM1-2 (P1.20) PWM pwm(PWM::pwm2, 1000);
To control the output of the PWM signal, a member function, pwm.set(float percent), will be called where percent is from 0 to 100. When percent is 0, the PWM signal is the lowest. When it is 100, the signal is the highest.
pwm.set(100); delay_ms(100); pwm.set(0); delay_ms(100);
LED matrix Interface
The figure on the right is showing how the LPC1758 and a shift register interface with a single set of LEDs of the same color. The strategy of LED matrix interface is to control to which LEDs along with which colors (green, red, blue) to be on or off. Each LED has 2 terminals, one is Anode(+) and one is Cathode(-). All the LEDs of the same row sharing the same Anode terminal, but different Cathode terminals. There are 8 Anode terminals controlled by the outputs of GPIO pins as in the figure on the right. There are 24 Cathode terminals, where every 8 of these Cathode terminals (of the same color) are controlled by the parallel outputs of a shift register. In order to turn on which LEDs, a control signal(CS) will select which shift register to be output. Meanwhile, outputs from GPIO pins to rows will turn on LEDs at desired locations.
For example, according the figure of LED matrix interface, if PO.26 is high and output Q0 is low, then the first LED will be on. If P0.26 is high but Q0 is high also, the first LED will be off.
The figure below shows how to turn on and off row1 on the LED matrix
spi1_ExchangeByte(0x00); enRow(1); // P0.26 is output high delay_ms(1); // LEDs on row 1 will be on for 1 ms disRow(1); // P0.26 is output low.
Where byte 0x00 will output from the shift register (Q0-Q7). As row 1 is enable by P0.26, a 3.3 voltage difference through resistors(220 Ohm in this project) will turn on the LEDs. Depending on the use of LEDs, different bytes of data will be sent and we can also enable which row to be active.
Software Design
In designing our Smart Cube we first identified the main software features of our system and how we should control them. The main features of the smart cube are the wifi communication, and the LED display. With these main features we then delegated the features into manageable tasks that would control and implement these features.
The Data Task is responsible for triggering the Alarm, sending the email and weather semaphores and initializing the global variables. This task is run in a medium priority in order to preserve other smart cube features; the LED display and the wifi service task.
The Service Task is responsible for managing the Wifi. This includes initializing the WiFly module, checking wifi connectivity, and retrieving the weather and email counts when the semaphore is received. The block diagram for this is shown in figure 2.
The terminal task is the basic terminal task provided in the SJSU Dev package. It is responsible for managing both UART1 and UART3, our usb and wifi data bus’s. This task allows us to issue commands from the website, or phone application as well as debug using Hercules terminal. The block diagram from the terminal task is shown in Figure 3.
The main purpose of the LED display task is to output data such as time, email, email count, weather, and alarm on the LED matrix. This task has the highest priority among all the tasks. If no task requires service, this task will display the real-time clock on the LED matrix. If other task requires service, it will output that service. For instance, LED display task will output alarm icon on LED matrix when the alarm trigger is set.
Hardware Implementation
After the design was complete and tested on Logic Works software, the hardware implementation took place on bread board. On the bread board, all the hard functions must be tested and confirmed before a real hardware is built.
Project View
Top View
Bottom View
Front View
Back View
Side Views
Software Implementation
FreeRTOS
The basis for our software implementation required using FreeRTOS, a real-time operating system. FreeRTOS, which is provided in the SJSU Developer package for the LPC1758, utilizes C and C++. It allows for the implementation of task, semaphores and queues, all of which are managed by the operating system. The previous labs, as well as the tutorials available on the Social Ledge website served as a reference for our design and implementation.
8x8 Matrix
The LED matrix is the output of hardware as well as software implementation. The procedure of outputting a number or a letter is broken up into steps, where every row and column are managed very carefully. The figure below shows how to output letter "F". Letter "F" will consume 3 rows corresponding to their column, and "pos" is the first row of letter "F". SPI sends 3 bytes of data because we want the data to be available at all 3 shift registers. This is fine because we can control the outputs of these registers using control signals (P0.15, P1.30, and P1.31). The first 4 lines of the code is to output the first row of letter "F" for 1 ms, the second 4 lines is to output a second row of letter "F", and the last 4 lines is for the last row.
void LEDdisplayTask::printletterF(int pos) { spi1_Exchange3Bytes(0x0E); enRow(pos); delay_ms(1); disRow(pos); spi1_Exchange3Bytes(0xAF); enRow(pos+1); delay_ms(1); disRow(pos+1); spi1_Exchange3Bytes(0xAF); enRow(pos+2); delay_ms(1); disRow(pos+2); }
The above code is just to output letter "F" for 1 ms. To output it for a longer time, a "for" loop can be use to hold it for a period of time.
for (int n = 0; n < 100; n++) { printletterF(pos); // pos depends on where to output }
Below shows how to shift a letter "F" from row 8 to row1 in Blue color. As pos decrements by 1,all rows of letter "F" will decrement by one, and letter "F" will shift to the left by one row.
selectchipBlue(); int pos = 8; while (pos > 0) { //decrement to the next position lower this number to shift display. pos = pos - 1; for(int i=0;i<40;i++) { printletterF(pos) ; } } deselectchipBlue();
Acceleration Sensor
This is an on-board sensor as show above (or show on the LPC1758 development board). The use of this sensor in the project is as a trigger to turn off the alarm. It is used to get the current locations of x and y and compare these values with the previous locations of x and y of the cube. The functions for this acceleration sensor are included in "acceleration_sensor.hpp" file. Below is how to use the sensor. It is in the "io_source.cpp" file.
short Acceleration_Sensor::getX() { return (short)get16BitRegister(X_MSB) / 16; } short Acceleration_Sensor::getY() { return (short)get16BitRegister(Y_MSB) / 16; }
Below shows how to get the value of X and Y and store to variables previousX and previous Y. AS.getX() and AS.getY() are to get the current locations of X and Y.
previousX = AS.getX(); previousY = AS.getY();
When the cube is moved locations of X and Y will be changed, the current locations of X and Y will be compared with the previous ones. If the absolute differences are 150, the alarm trigger is off.
void LEDdisplayTask::DetectMovement() { //turn off alarm by moving the cube //compare current locations of x and y with the previous ones. // if the difference is 150, turn off the alarm trigger if ((AS.getX() < (previousX - 150) || (AS.getX() > previousX + 150)) || (AS.getY() < previousY - 150 || AS.getY() > previousY + 150)) { turnOffBuzzer(); g_AlarmTriggered = false; printf("Alarm is off\n"); } }
WiFly
The management of the Wi-Fly and wifi connectivity was done in the services task. This task was responsible for initializing the Wi-Fly with the appropriate values and connecting to the defined SSID. With the Wi-Fly connected to a SSID it was the service task responsibility to ensure that a connection was established and maintained. With a connection obtained the Wi-fly module could access the smart cube website and receive data as a tcp client and server.
The pseudo code for connecting to a SSID and enabling the WiFly module as both a tcp client and server is as follows:
//Set connection parameters Enable dhcp Define the ssid Define the protection type (wep, wpa, etc..) Define pw Define channel Define mask //Set communication parameters define close define open define remote //Set flush parameters set comm size set timeout length set idle time //Set TCP paramters set to client and server(variable “2”) define port number Save Reboot
Get Weather
In order to obtain the weather the smart cube acted as a tcp client utilizing the World Weather Online api at (api.worldweatheronline.com). Using this api we were able to configure the wi-fly module to request the weather in a http 1.0 format. In order to do so the Wi-Fly must act in TCP Client mode, connect to the source ip, and perform a “get” to retrieve the data desired. An example of getting the weather from the api is shown below:
wifiSendCmd("open api.worldweatheronline.com 80"); mWifi.put("GET http://api.worldweatheronline.com/free/v1/weather.ashx?q=CITYformat=csv&num_of_days=1&key=API-KEY HTTP/1.1");
From this http response we were able to parse the data looking for the temperature. The example format of the http response not including the header is as shown below:
#The CSV format is in following way:- #First row will always contain the current weather condition. if for any reason we do not have current condition it will have 'Not Available'. #The current weather condition data is laid in the following way:- #observation_time,temp_C,weatherCode,weatherIconUrl,weatherDesc,windspeedMiles,windspeedKmph,winddirDegree,winddirPoint, precipMM,humidity,visibility,pressure,cloudcover # #The weather information is available in following format: #date,tempMaxC,tempMaxF,tempMinC,tempMinF,windspeedMiles,windspeedKmph,winddirDegree,winddir16Point,weatherCode, weatherIconUrl,weatherDesc,precipMM # 05:04 AM,15,113,http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0008_clear_sky_night.png,Clear,11,17, 320,NW,0.0,63,16,1018,0,2013-05-15,21,70,11,52,13,21,320,NW,113, http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png,Sunny,0.0
The data can be obtained in various formats, including CSV, JSON, and XML. In our usage we found CSV the easiest format to parse, as we could easily traverse through the response using the “,” as our delimiter.
Get Email Count
Similarly to retrieving the weather, the process of obtaining the email count was done simply by accessing the getemail.php file that is hosted on the server. The first step in obtaining the email count is connecting to the server as a tcp client. Then the url can be sent with the appropriate php parameters in the url. The process of connecting and obtaining the email count is shown below:
wifiSendCmd("open SERVER-IP 80"); mWifi.put("GET http://SERVER-IP/getemail.php?username=USERNAME&pass=PASSWORD HTTP/1.1");
Web Server
The hosting of our webserver was done on a Raspberry Pi. Since we spend a significant amount of time developing at school, we found that connecting to a remote server with the Wi-fly module was nearly impossible since the SJSU wifi would not release an IP. In order to resolve this we turned to using a local webserver to satisfy our testing and development needs.
The Raspberry Pi was setup with the standard rasbian “wheezy” linux distro, which can be found here: http://www.raspberrypi.org/downloads . With the distro setup and an active Internet connection the Apache and PHP server could then be installed. In order to do so, the following commands were issued to the command line (NOTE: this can be done over SSH as well).
sudo apt-get install -y rpi-update sudo apt-get update -y && sudo apt-get upgrade –y
Now your raspberry pi is up to date and you can proceede with installing apache and setting up the appropriate permissions.
sudo apt-get install -y apache2 apache2-utils sudo groupadd -f -g33 www-data sudo chown pi:www-data /var/www sudo chmod 775 /var/www
Lastly you will need to install PHP and curl this is done with the following command:
sudo apt-get install -y php5 libapache2-mod-php5 php5-common mysql-client sudo apt-get install -y php-pear php5-mysql php5-curl php5-gd php5-idn php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-json
Now is a good time to reboot the raspberry pi with the following command:
sudo reboot
Once the raspberry pi is fully booted you can test to see if Apache and PHP were successfully installed. To do so, create a file called test.php in the vars/www/ folder and add the phpinfo(); function, as shown below:
sudo nano /vars/www/test.php //add text <?php phpinfo(); ?>
If the php information shows on your screen when you navigate to: www.RAPBERRYPI-IP/test.php then you successfully configured your raspberry pi as a webserver.
Web Interface
In order to send commands to the smart cube in an efficient and intuitive way a user interface was needed. Ideally an interface or solution that did not require installing a program or additional software on the users end. For this reason we utilized the already existing wireless features of our system to send commands from a website. The website functions included:
- Setting the Alarm Time
- Setting the City of the Weather
- Defining the GMAIL Credentials
- Setting the Time Interval
- Future Features
Front End
The Front End of Web interface involved utilizing HTML, in conjunction with JavaScript to display and send data using JQUERY and AJAX to the back end. In designing the front end of the website our goal was simplicity and ease of navigation. In order to do so we utilized large interactive, self-intuitive buttons, and an IFrame to focus on pertinent information. Our implementation was all done by hand, using notepad++ and Filezilla as our ftp client. The buttons on our layout were obtained from http://dabuttonfactory.com, a neat tool that allows for the creation of custom buttons. The first image shows the home page, utilizing the large self intuitive buttons.
In order to send data to the back end of the server for processing, we utilized the JQUERY JavaScript plugin to post data to a PHP file. The PHP file could then analyze the data and perform the necessary functions as discussed in the next section. It is important to note, unlike other coding languages, Javascript is event driven. That is functions and operations are performed and when a specific event is triggered, such as a button click. One such example of an event driven function in javascript is the showing and removing of a button shadow when a cursor hovers over a button. Some sample code for this is shown below:
$(".Shadow").hover( function() { $(this).attr("style", "box-shadow: none;"); }, function() { $(this).attr("style", "box-shadow: 0px 2px 22px #4B91A5;"); } );Note: this utilizes JQUERY which is denoted by the “$” identifier before the event function. This code is typically placed in the “OnLoad” portion of the javascript file. This image shows the result of pressing the alarm button, opening the alarm.html page in an IFrame.
Back End
The back end of the web interface implemented using PHP on a Linux Apache Server. We chose Linux because it was readily available on our development computers and we could deploy a mobile server using a raspberry pi. The back end PHP functions of our server consisted of:
- Sending commands to the Wi-fly module via a TCP Connection
- Set Alarm
- Set City for Weather
- Send Email Count
- Setting the Time Interval for Weather and Email Notifications
- Retrieving the email count from a RSS Gmail feed
Sending Commands to the Wi-Fly Module
In order to communicate to the board the server needed to send commands regarding the users action on the webpage. These commands included:
- Alarm set HH MM
- Alarm clear
- Weather set CITYNAME
- Email set USERNAME PASSWORD
- Fetch set HOUR
The triggering of these commands is done when a user navigates to the various pages and submits data. When data is submitted on the webpage a jquery event is triggered and data is posted to the appropriate php file using ajax. The post contains the “action” or function to be called, and the various parameters needed in the command. When sending a command to the Wi-Fly module the server acts as a tcp client and connects to the wi-fly module at the designated ip and port 5555. Once connected the tcp client can send its desired information and the smart-cube will treat the information just as it would a command given over Uart-0.
Getting Email Count
The first set in attempting to obtain the email count on our server was creating a PHP file that would be called from the Wi-Fly board every time the Smart Cube requested the email count. This PHP’s file’s purpose was, with the given parameters, call its internal “get email” function. The parameters are passed to the PHP function in the url in the following format:
www.smartcube.com/getemail.php?param1=value1¶m2=value2
The parameters used in our case were just the email id and the email password. With this information PHP’s cURL utility in conjunction with Google’s atom feed would be able to retrieve the desired information.
In order to obtain the email count from google’s “atom” feed, the cURL library was used. cURL on in a primitive description is like a internet browser without the UI. It allows for a PHP to create a session and access webpages data in html format. For the purpose of collecting the email count of a Gmail account curl was used to create a secure connection to https://mail.google.com/mail/feed/atom. Once a oAuth connection was made data would be retrieved in a xml format similar to this:
"<?xml version="1.0" encoding="UTF-8"?> <feed version="0.3" xmlns="http://purl.org/atom/ns#"> <title>Gmail - Inbox for BLAHH@gmail.com</title> <tagline>New messages in your Gmail Inbox</tagline> <fullcount>100</fullcount> <link rel="alternate" href="http://mail.google.com/mail" type="text/html" /> <modified>2013-5-12T12:33:48Z</modified> <entry> <title>Blahhh EMAIL</title> <summary>This is some sample summary text!!</summary> <link rel="alternate" href="http://mail.google.com/mail account_id=BLAHH@gmail.com&message_id=123456&view=conv&extsrc=atom" type="text/html" /> <modified>2012-5-12T12:12:44Z</modified> <issued>2012-5-12T12:12:44Z</issued> <id>tag:gmail.google.com,2004:1234567890</id> <author> <name>BLAHH Author</name> <email>FROM_EMAIL@Blahh.com</email> </author> </entry> <entry>"
The next part would be to parse the xml data looking only for the email count in our case. By accessing the xml tag “fullcount”, as a SimpleXMLElement, we were able to parse the response for the current unread email count.
More information regarding cURL and its used in PHP can be found here: http://php.net/manual/en/book.curl.php
Windows Phone 8 Application
The purpose of the Windows Phone 8 Application was to provide another convenient interface for communicating to the Smart Cube. The communication method to the Smart Cube from the WP8 application is done through TCP/IP. By utilizing TCP/IP we did not need to reinvent the implementation of communicating to the Smart Cube. Rather with TCP/IP we were able to access the smart cube just as we did with the PHP services. Creating an application to connect to a TCP socket was very easy, considering the wealth of information available on the Internet.
By utilizing the following article, which discusses setting up a TCP application, we were able to integrate all the desired features of our existing website into a mobile application. http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202858(v=vs.105).aspx
The WP8 application opens up requesting the IP and Port number of the Wi-Fly device, an attempt is then made to connect to the board. The process for connecting to the wi-fly module from the windows phone application was done by following the previously mentioned tutorial. This tutorial began by setting up the SocketClient Class, with a connect function, and send data function. The basics of this class included utilizing the innate .NET TCP stream and DNS endpoint libraries. With these libraries a socket connection can easily be made and with supporting functions data can be sent to a tcp server.
Testing & Technical Challenges
Testing
The primary tools we used were for testing was Hercules, the debugging potential and testing with Hercules are endless. Hercules allows for testing of not only the usb uart0 communication, but it allows for debugging a tcp client or server. Using Hercules we were able to test our PHP server functions, buy acting as a client and making a request to the PHP server. As well we were able to test the weather api. The process of testing the PHP server function from Hercules is as follows: 1. At the TCP client tab a. Input the server IP b. Input the server port (if a php request, use 80) 2. Click connect a. Result should be “Connected to IPADDRESS 3. In the input box type a. GET “IPADDRESS/myfunctions.php \n\n\r\n 4. The output should be the result of the executed PHP file.
Test Cases
The execution of test cases was done manually, and the results were then verified with the expected output.
Alarm
- Set the Alarm
- Set the Alarm more than once
- Clear the Alarm
- Clear the Alarm while Triggered
- Set the Alarm while Triggered
Weather
- Set the Weather City
- Get Weather without Internet connectivity
- Set the email
- Set the Password
- Get the Email count
- Get the Email Count without Internet connectivity
Technical Challenges
During the implementation of the smart cube, we encountered numerous testing and technical challenges. These challenges ranged from the implementation of the 8x8 led matrix to the interfacing of the web server to the development board.
RGB LED matrix implementation
There were multiple issues encountered during the implementation of the LED matrix such as the use of shift registers, the output of a number or a character, and SPI communication.
Shift Register
This was the first problem encountered when implementing and testing the spi communication between the CPU and the shift register. A shift register 74HC595 has to two parts, one is an 8-stage shift register and one is an 8-bit storage register. The problem was to get the data from the 8-stage shift register and store to the 8-bit storage register because the misuse of the shift register clock input (SHCP) and the storage register clock input (STCP). We got wrong data all the time because we did not synchronize the two signals with the clock input from the LPC1758. The problem was solved after we connected the two signals with the clock input.
SPI Exchange
This was the second major problem during when using SPI to exchange or transfer data. It is still unclear that the first spi-sent byte is not always captured correctly by the shift register. For instance, when we use "spi1_Exchange3Bytes(char data)" to send data to all 3 shift registers (Green LEDs, Blue LEDs, and Red LEDs are controlled by first,second, and third shift registers respectively ), the first sent byte will be shifted to the third register, the second byte is shifted to the second registers, and the last byte will stay at the first register. The data is captured correctly at the first and second register, but not captured correctly at the third register.
The first approach to this problem was to delay the output control signal of the shift register for some Milli-seconds or micro seconds because we thought that the CPU speed was running so fast causing the first sent byte not captured correctly. However, this approach did not work.
The second approach was to send one more byte to the shift register. This means instead of sending three bytes to shift registers, the CPU then sent 4 bytes. Finally, this approach fixed the problem. This might not be a good approach at the engineering level, but it solved our problem.
Output a digit or a character
This problem involved with timing analysis and how to manage the outputs correctly. A digit, for instance, has to be output in 3 rows and columns (depending on the height of the digit). To output a digit on the LED matrix, we first sent a byte of data using spi communication to the columns for a digit, then turn on the first row for a small period of time such as one millisecond. Then, we continued the same step for the second row and third row for that digit. However, the whole process happened very quickly that we just saw a flashing digit on the LED matrix. To solve this problem, we want this process to be repeated for a number of time, so we could see the digit clearly. A "for" loop was used to repeat and output a digit.
Note: Rows and column are used corresponding to the LED matrix schematic.
Web Server Multiple Commands Issue
During our implementation of the Web server we were encountering a very strange error. This error occurred when two commands would be sent consecutively from the web server. An example of this was:
Alarm set 12 15 // this should set the alarm to 12:15 alarm clear // this should clear the alarm
The response from this execution in the Hercules terminal would report: “alarm set” which was correct, and then it would report “command not found”, which is incorrect. I was expecting to see that both commands were “set”. In order to debug this, Preet suggested we print the received command with “|” surrounding the command. The result was:
Command: |set alarm 12 15| Alarm set Command: | alarm clear| Command not found
Immediately we noticed that there was a “random” whitespace character in the command code. In order to resolve this we attempted to have the getline command ignore the whitespace character “0x20”. We soon found out that this did not work, because the first character was not a white space! After some detective work, printing the first character via the printf function:
Printf(“%x”,firstchar);
We found out that the first character was in fact the first character was “0x09”. After back tracking to the location where the command was sent, we found that in the php function to send the commands a literal newline character was being sent. The reason for this was inexperience with PHP. In PHP you can escape a new line character ONLY in double quotes. Rather we were just using a literal newline at the end of the command; unknowingly Notepad++ was adding a tab character to format the new line. The difference is shown below:
Desired:
Result of Notepad++'s auto indent:
In order to resolve this issue we utilized single quotes and used the “/n” character to escape our commands. After making this change to all the php functions that sent commands to the wifly module this issue was resolved.
Conclusion
In this project, we have successfully finished our goals and tasks such as interfaces that allow the user to select the desirable functions of the cube: alarm setting, weather location, and RTC clock. We are able to perform these tasks and demo them precisely. Also, we added some more features to our Smart Cube such as email notification, moving the cube to turn off the alarm as it was planned to use a switch, as well as selecting different melody or ringtones for alarm sound.
There were a number of problems encountered during the hardware implementation such as the use of shift registers, the output of a number or a character, and SPI communication. It took a while to figure what caused which problem, then we were able to have different approaches to solve the problem as discussed in the testing and technical challenges section.
This project have shown a large concept of how an Embedded System as well as all the interfaces between the CPU and I/0 devices. We were able to manage between software and hardware and understand the relationship between them such as using FreeRTOS to communicate and perform different tasks with different levels of priority.
Project Video
Project Source Code
References
Acknowledgement
Dr. Haluk Özemek
Preet Kang
References Used
[1] How to build a 8x8 RGB LED Matrix with PWM using Adruino *[1]
[2] 8x8 RGB LED matrix
[3] 74HC595 Shift Register datasheet
[4] RN-XV Wifly wifi module
Appendix
You can list the references you used.