Preet's Relay Controller Project
Contents
Overview
The motivation of this project is to control a relay board over the network (or even over the internet). More specifically, this project is an application of the relay control in the form of a sprinkler control system (SCS). Overall, the following functionality is targeted:
- Schedule a run-time
- Select days to water
- Select run-times of each sprinkler
- Turn System On or Off
- Set 'Rainy days' (number of days to skip a scheduled run)
- Connect to Internet and check weather to automatically turn off sprinklers on rainy days.
The extended functionality is the Web GUI*. The Web interface (WI) not only allows to control SCS, but also view the logs in a graphical way. For example, WI can request daily water-times from the SCS and plot a bar-graph to show the user the water history.
Features
Commandline Interface
The command-line interface (CI) is an intuitive interface that is a self-documented piece of SCS. To begin using the interface, all it takes is to connect SCS to a USB port on a computer, and open the COM Port at 38400bps and type "help". Below are some screenshots of the command-line interface.
Commandline over TCP/IP
The CI is the same over TCP/IP. All it takes is to open up a TCP/IP port of SCS and use the same commands. SCS uses fixed port number: 5555 of TCP/IP. To open CI over TCP/IP, SCS IP needs to be first determined and then the Hercules* utility can be used to interface with SCS. Below, you can see the relay command sent. Since this is a nested command, typing just the name of this command lists the sub-commands underneath it.
SCS Command Example
To begin, "relay help" command can be issued to see the command-set. To schedule the SCS to water plants everyday, the following commands can be issued:
- relay schedule 18:00
- relay minutes 1 1 1 1 2 2 2 2 3 3 3
- relay power on
- relay waterday everyday
- Other examples: 'relay waterday mon' or 'relay waterday not monday'
- This command is flexible and doesn't require weekday to be spelled correctly.
- Adding a 'not' turns off that weekday's scheduled time.
Web-based Controls
SCS exposes its interface over a TCP/IP connection. It provides a simple, human readable CI. This CI is encapsulated in the WI that provides an even simpler interface to an end-user. The idea is that a person without any knowledge of the controller should be able to interact with the system.
Logs
There are several forms of logs that get saved in the file system accessible by FAT* library. These logs produce useful data that the WI can interpret and create graphs from. In the end, there are two useful things that come out of logs:
- Graphical view of the system and data
- Long-term debugging capability.
The SCS software saves the log in the on-board 1Mb SPI flash memory. This provides capability to save data without relying on an external SD card. Due to the FAT* library used, the files can be transferred to the SD card and read on a computer as well.
Hourly Sensor Logs
Every hour, temperature and light sensor value is logged into a file in the format:
9/16/2012, 14:00, 76.25, 100
9/16/2012, 15:00, 77.25, 150
9/16/2012, 16:00, 78.75, 130
Nightly Logs
Every night, a log message saves the number of minutes SCS turned on relays in a 24-hour period. This serves as a daily log of the number of minutes plants were watered.
9/16/2012, 25
9/17/2012, 0
9/18/2012, 25
Debugging Logs
Debugging and informational logs also get saved on demand or if the log-buffer becomes full. This can open the gate for long-term testing and debugging to ensure that the software is operating as expected.
9/16/2012, 14:00, Relay #1 ON
9/16/2012, 14:05, Relay #1 OFF
9/16/2012, 14:05, Relay #2 ON
9/16/2012, 14:06, All Relays OFF
Daily Weather Check
SCS checks weather information on a nightly basis. A few hours after mid-night, SCS checks weather information and sets the Rainy Days automatically. This is a useful feature to conserve water. The implementation section describes how SCS performs this nightly activity.
Implementation
Hardware
In the hardware level, the following components form SCS:
- SJ-One Board
- RN-XV Wifi module
- Relays attached to GPIOs
The wifi module is a simple UART based TCP/IP solution. The SCS software initializes RN-XV, sets up a TCP/IP port to listen to, and simply waits for data or command from UART and responds back to the command.
GPIO Relays
Eleven relays were attached to GPIOs of the SJ-One board to switch 28v AC output. The relays were purchased from Ebay that contained a built-in LED indicator of the relay outputs. The software simply turned on and off the relays as instructed which in turn would switch on and off sprinklers.
Embedded Software
FreeRTOS template project was used to provide the software framework. This software framework was extended by adding more command-line handlers.
Tasks
Three tasks exist in the software:
- Terminal Task
- Handles all command inputs and routing the commands to appropriate command handlers
- SCS is configured through commands by this task
- Wifi Task
- Associates RN-XV to Wifi Network
- Monitors disconnect and attempts to reconnect
- Checks weather nightly and sets rainy days automatically
- SCS Task
- Handles servicing relays every minute
- Logs data on hourly and nightly basis
Files saved on SPI Flash
There are several files saved on the on-board SPI Flash which are worthy of mention.
- Scheduler settings
- Saved under schedule.bin to save the SCS relay schedule
- Wifi settings
- Saved under wifi.cfg. This file contains the SSID and WPA phrase used to connect to Wifi.
- This provides capability to change wifi settings easily without reprogramming the SJ-One board.
- Logfiles
- hourly.csv: Hourly temperature and light sensor logs
- watered.csv: Nightly log of one day's watertime
- log.csv: Debugging logs that log information or system errors
- boot.csv: Logs timestamp each time system reboots.
- cmd.csv: Saves all the commands issued through RN-XV Wifi
Scheduler Class
There were only a few modifications to the SJ-One Software Framework:
- Additional commands
- Scheduler class
- RN-XV Wifi handler
The scheduler class is the primary modification to the SJ-One Software Framework. Note that this has nothing to do with Operating System scheduling, but it is the scheduling of the relays. Here are some useful members of this C++ class:
- Turn On/Off Scheduler
- Get/Set Scheduled Time
- Get/Set Relay timings
- Get/Set Waterdays
The modifications and status was handled through commandline commands. The schedule was saved in a binary file on the on-board SPI Flash. To minimize the number of times this file was written (avoid flash wear), a five minute delay timer was implemented. Whenever the schedule was changed, the schedule was marked dirty. After detecting no schedule change for five minutes, the schedule from RAM was saved to Flash memory.
Daily Weather Check
To check weather information such that SCS can set Rainy Days by itself, SCS acts like a HTTP client to obtain data over the Internet. After some research, World Weather Online website was used to provide a simple set of data containing the weather information. To get weather information, an API key was obtained after signing up and then a simple TCP/IP packet was exchanged.
Although being an HTTP client may sound complicated, a simple HTTP client is nothing but a TCP/IP package exchange. The following steps illustrate how this occurs:
- SCS connects to www.worldweatheronline.com on Port 80.
- Note that port 80 is the standard TCP/IP web-server port.
- SCS sends HTTP GET request:
-
GET http://free.worldweatheronline.com/feed/weather.ashx?q=95050&format=csv&num_of_days=2&key=<your api key>
- Send "\r\n\r\n" after the GET data above.
-
- World Weather Online will send a CSV response and close TCP/IP connection.
The web-server will now respond with data that can be parsed to find out if it will rain in upcoming days. One can use Hercules utility and test this method by using a TCP Client connection. Below is the exact response obtained but note that some irrelevant lines were deleted as denoted by ...
HTTP/1.1 200 OK
Cache-Control: public, must-revalidate, proxy-revalidate
...
...
#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,winddir16Point,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
#
09:16 PM,20,113,http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png,Sunny,11,17,290,WNW,0.0,59,16,1017,0
2012-10-08,19,66,13,55,11,18,240,WSW,116,http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png,Partly Cloudy,0.0
2012-10-09,18,64,13,56,11,18,270,W,122,http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0004_black_low_cloud.png,Overcast,0.1
Psuedo-code
RN-XV is primarily acting like a TCP/IP server, but when weather-check is performed, it temporarily acts like an TCP/IP client. Here is the psuedocode that allows to quickly switch between the server and client modes and get weather data:
void check_weather(void)
{
rnxv_enter_command_mode();
rnxv_send("open www.worldweatheronline.com 80\n");
wait();
// Connection as client will be made
// RN-XV will exit command mode
// Now communicate with the web server
rnxv_send("GET foobar\n\n\n");
// Receive the response
// Response may be large, so apply your filters such that
// only relevant information is stored into buffer.
rnxv_receive(buffer);
parse_http_response(buffer);
}
RN-XV works really well between server and client. When TCP/IP request using open command is sent, it automatically connects as a client and exits command mode. From then on, it is just a matter of exchanging a HTTP information. The server will close connection and thus RN-XV will automatically disconnect and go back to its TCP/IP server configuration. No further commands are required to set it back to TCP/IP Server after using its TCP/IP client mode.
Hints
Note that the Hercules utility can be used to exchange information with World Weather Online HTTP server. This can help implement the RN-XV code because the command and response of HTTP can be visually seen.
RN-XV Initialization
The RN-XV Wifi module is initialized to obtain an IP via DHCP, and then act as a TCP/IP server on port 5555. The basic operation of RN-XV is as follows:
- RN-XV boots with UART speed of 9600bps
- RN-XV commands can be issued in Command Mode
- To enter command mode, send
$$$
- No characters should precede or follow
$$$
for 250ms.
- To enter command mode, send
- To exit command mode, issue
exit\r\n
- If RN-XV is not in command mode, all data received over UART is treated as data for an established connection.
Setup IP & Associate
RN-XV can be commanded through it's UART interface to initialize it. For this project, WPA2 security is used which is an optional setting. After each command is sent, the user should wait for the RN-XV's response before issuing further commands.
- Enter command mode:
$$$
- Enable DHCP:
set ip dhcp 1
- Set SSID:
set wlan ssid <Your_SSID>
- Set WPA2 Security:
set wlan auth 4
- Set WPA2 Passphrase:
set wlan phrase <My_Sec_Phrase>
- Set all channels:
-
set wlan channel 0
-
set wlan mask 0x1FFF
-
Setup Parameters
(Continued from previous section):
- No 'Greeting' messages upon connection:
-
set comm close 0
-
set comm open 0
-
set comm remote 0
-
- Setup Flush Parameters:
- Disable character flush:
set comm match 0
- Set Flush size:
set comm size 1024
- Disable character flush:
To optimize data transfer, a character triggering flush is disabled and the flush size is set to 1024 bytes. When RN-XV receives no data transmission within 10ms, any outstanding data is sent from its RAM to the network (default setting). In the configuration above, whenever 10ms timeout occurs or 1024 characters are sent to RN-XV, it will send the packet over TCP/IP.
Setup TCP/IP Server
(Continued from previous section)
- Use TCP/IP Protocol:
set ip protocol 2
- Use your port:
set ip local port 5555
- Save and reboot:
-
save
-
reboot
-
Wait about 1-5 seconds for reboot and association to finish. In case your RN-XV doesn't connect to your wireless network, enter command mode and command it to join your SSID:
-
join <Your_SSID>
-
After performing these steps, RN-XV should have obtained an IP address and it is ready to communicate over TCP/IP port 5555.
Front-End Web Interface
While the SCS software can interact with the CI, WI encapsulates commands with simple buttons. This provides a non-technical person the capability to control the system.
Web Server Implementation
A web server is required with knowledge of the SCS IP and port. See the details below about how the web server interacts with the user and the SCS:
- User requests SCS web page "http: // home"
- Web server responds back with the web page
- User clicks on web page control elements (ie: "Turn Off")
- Command is handed off to the web server
- Web server contacts SCS and obtains a response
- Web server responds back with the SCS response
- User is notified on the web page of the request' status.
Web Development Tools
Since the Web-Interface (WI) was not the primary focus of the project, the web implementation is not discussed in great detail, however, there were two primary web development tools used in the project briefly discussed in the next sections:
Bootstrap from Twitter
Bootstrap is a great web developer tool to create nice looking web pages. This was used to create buttons and the overall layout of the web interface. The Bootstrap package also provides a package of javascript utilities that one can utilize to further enhance a web page's appearance.
To get started, one can download the Bootstrap zip file, deploy it on a web server, and start from index.php or index.html.
Google Charts
To improve the appearance of the statistics, Google charts were used to display information. This includes the gauge that displays the temperature and memory capacity along with bar-charts that show the water history. To use the charts, only a couple of changes to your index page are needed:
- Include Google javascript:
- <script type="text/javascript" src="http://www.google.com/jsapi"></script>
- Load the API:
- google.load('visualization', '1', {packages: ['corechart']});
After setting up the index page, Google API can be referenced to draw actual charts.
Testing
The testing was performed manually by verifying the command and expected output. The steps were:
- Program the software
- Test each command through UART interface
- Test each command through Wifi interface
- Test Web Interface
Test Cases
Simple Test Case
- Set a schedule and run-time in minutes.
- Enable each day as a 'waterday'
- Wait until the system time reaches scheduled time
- Check 'relay status' periodically to verify the results
- Check the log file to make sure relays turned on and turned off as appropriate
Corner Case Test Cases
- Repeat the Simple Test Case with the following:
- Rainy days set to non-zero
- Weekday as not a 'waterday'
- SCS set to OFF: No system activity should exist
Logfiles test case
- Test to make sure hourly and nightly logs are written correctly
- Verify this by using the CI command:
read hourly.csv -print
- Verify this by using the CI command:
Web Control Tests
- Repeat the Simple Test Case but through web controls.
Problems & Resolution
This section lists the problems encountered and the approach taken to resolve the issues.
Periodic Software Processing
It was a little tricky to periodically perform actions such as once a minute or once a day. The RTC interrupts were setup to 'give' binary semaphores, however, the log-files discovered that the 'One Day' semaphore was being given every minute from 00:00 to 00:59. The solution was to refactor the branch statements of RTC semaphores and only give the 'One Day' semaphore when seconds, minutes, and hours equal 0.
Inaccurate Temperature Sensor
Temperature Sensor had issues with accuracy because it picked up the SJ-One Board's surface temperature rather than than the air temperature. This issue wasn't fully resolved, but it can be resolved by doing a new board revision.
Sending Data over TCP/IP
When the WI asked for log data, the PHP socket only obtained the first response, and immediately closed the connection and responded back to WI. The problem with this method was that when sending a large log file, it would truncate the data after the first packet. One way to solve this problem is to keep appending TCP/IP data until there is no data obtained within 250 milliseconds or so. This however, would've slowed down the transmission of a quick command/response system. The solution adopted was to pass an extra parameter called expecting_large_data
to PHP. Now, when PHP saw this, it would append data with 250ms timeout, and at the same time return quick responses for commands that do not return large amount of data.
View Log files in WI
Log files of SCS could get very large and it could become difficult for WI to request large amount of data. To solve this problem, an additional command to SCS was added: readlog <start date> <end date>
. SCS would now parse through the file and only send back the logs from the selection.
Conclusion
A very low powered relay system was developed that has capability to be controlled over the Internet. This solution is a completely encapsulated system that can be controlled by a USB/UART interface, or over a TCP/IP interface.
The RN-XV Wifi module is an exceptional piece of hardware at a relatively great price ($35 per unit). Although I've done projects using SPI Ethernet module (by Microchip), it required integration of uIP (from Adam Dunkels). The advantage of using uIP is that you can support more than one TCP/IP or UDP port communication but the disadvantage is the huge code base that you have to integrate and test. Furthermore, RN-XV is a wireless solution which yields more flexibility.
During the project development, I enhanced the project by being able to transfer files through a command-line command. This enhancement allowed me to transfer new software binaries to the board, and then program the binary to the processor's flash memory. In other words, I was able to reprogram the board over-the-air saving enormous amount of time during development and testing while the project was working as a live-unit in the house garage.
Future Enhancements
Initially, one of the future enhancements was to check weather information and set Rainy days of SCS automatically, however, after researching how simple this was, it was implemented with ease. To enhance this further, a similar enhancement can include various weather sensors attached to SCS such that it can have even more intelligence of when to water the plants.
Source Code
You can grab the source code of my deployed project from SourceForge SCS