alternatasha a site to catalog random projects

diagram_950x425

wireless home sensor network, part I

Currently, home sensor networks, whether utilizing Xbee, Wifi, or other frequencies, are relatively expensive, unavailable, or simply unuseful. A low-quality security camera needs several other pieces in order to work properly, looks too industrial for a home, and carries a high price tag. Simple sensors, such as temperature and humidity loggers (such as the popular ‘weather stations’), tend to break within months. All this leads to the fact that relatively few people have even a basic sensor network at home. What is sad about this observation, is that in most modern societies, every house already has a modem and wifi router on and running twenty-four hours a day, seven days a week. Unknown to most, these routers can serve as sensor network sources, and usually have enough processing power, as well as hardware space, to process data and/or set up a small web server. This paper attemps to catalog the process of setting up a home wifi network, starting with the main base (the router), and slowly moving outward toward several, modular, standalone ‘nodes’ which capture some sort of data and pass this back to the source.

Introduction

There are several open-source projects that got me thinking of the myriad possibilities in sensing and automating the home. Listed below are a few:
the tweeting cat door
home power monitoring
wifi-enabled whole house meter
RF data link
RFID access control system

At my residence, there is an outside gate that is normally closed and locked from the outside. For a long time there was no bell, so I often missed packages. Recently, I installed a simple wireless transmitter bell (see image below). This has helped me to know when someone is trying to contact me from the street, but it does not let me know who is ringing the bell. The new bell does not log rings, cannot tell me who came to the gate, or if someone attempted or succeeded in forcing the gate open.

"wireless bell""chime"

315MHz RF link

The wireless transmitter, by Heath-Zenith, operates at 315 MHz. (Note: other manufacturers use different frequencies. Common frequencies are 433 MHz and the now-ubiquitous 2.4GHz.) This device connects to a chime with matching frequency and matching code. There are seven switches on each of the transmitter and receiver that, when in the same pattern, help ensure a robust connection with less chance of interference from other transmitters. With this RF link, I already have a signal from outside the house to inside, and I could use this to trigger a camera to take a picture of the gate area. This image could then be sent back to the router to email or text me right away — in this way, no matter where I am at the moment (assuming I have my cellphone with me), I will know if someone is at my door. (While I had hoped to add security to this system through rfid reading at the gate, the parts ordered did not arrive in time for this part of the project.)  The figure below shows the main plan in a simplified diagram.
initial plan in a diagram
Initial plan in diagram form

Parts

Router
"router stack on wall"

Original Home Netwoork Setup, from top down: modem, wifi router, voip adapter, power strip

The router, being the central unit of the wifi network, is also the first part to set up. Like most people, I bought my wifi router years ago with no inkling of what it really could do besides connecting to my modem to provide wifi to my apartment. Because of this, I did not pay attention to specifications such as processing speed and physical/flash memory. My old Netgear router was set up in a stack in between the modem and peripherals, which included a VOIP adapter as well as my main computer (see figure on the right).

The wifi router was a Netgear RangeMax Wireless Router model WPN824v3. For extra functionality and the ability to run scripts as needed, I had to flash an open-source software onto it. There are several choices in today’s ‘free’ marketplace: DD-WRT, OpenWrt, Tomato, FreeWrt, and others. However, I chose to go with the one that is most open-source, modular, and customizable: OpenWrt. There are a few Netgear router models that are known to work with OpenWrt, but not mine. For this reason, I decided to check Craigslist for a cheap, yet easily customizable, router to play around with, and possibly ruin, for this project. The router model which originally spurred the idea of flashing, customizing, and developing router software was the Linksys WRT54G. These routers are practically mini-computers, with loads of processing power and physical space to add software. OpenWrt requires, at the absolute minimum, about 2 gigs of memory; I was looking for as much as I could get.

Luckily, I found Robert in Harlem willing to sell his old Linksys WRT54GS version 2.1 for $35. This model is perfect for my application — it has a 216MHz processor, 32 MB of RAM, and 8MB of flash memory. This gives enough room for a fresh installation of the latest OpenWrt software as well as more packages, apps, or scripts as I go along. Next the Linksys was flashed with OpenWrt software. By following the directions on the OpenWrt website, this process was not difficult, but care had to be taken not to ruin the configurations later. Despite my best efforts, I still managed to ‘brick’ the router within 5 minutes. I could not communicate with it, since the ethernet ports were somehow disabled. This meant that I would have to open it up and create a serial connection to the router in order to fix, or reflash, the software. Opening the router proved to be surprisingly difficult, and I needed the help of a guide online. (My model required removing two screws hidden under the front feet first.) The middle image below shows a close-up of the serial port, for which I soldered the pin header on first to get a better wire connection. The picture on the right shows the FTDI serial to usb adapter that is necessary to communicate through the computer. A 3.3V FTDI adapter is needed to match the router’s voltage level correctly.

"linksys router""linksys serial connection""linksys serial to usb connection"

Router for OpenWrt open software, showing serial connection

A small program on the computer (I used cutecom, after trying and failing with several others) provided the interface with the usb port — setting the baud rate, parity, number of bits, and port number correctly was imperative. For this router, the settings were 115200, 8, None(for parity), and 1 (stop bits). The program would only recognize and communicate with the router if I plugged it in at the same moment that I opened the connection. While the router powers on, information dumps onto the screen. At some point in the middle of this, it says to press ‘f’ to enter failsafe mode. This did not work the first several times, but when it finally did, the OpenWrt prompt appeared, waiting for my command. At this point, a simple firstboot command reconfigured the software to the original settings so that I could start configuration all over again. One webpage that helped with different types of configuration can be found here. There are two ways to communicate with the router from an attached computer: 1) through telnet (see screenshot below) and later, ssh, and 2) through “LuCI” the Lua web interface.

"openwrt telnet screen"
Initial communication with router through telnet

Wifi Module

After the router is set up with customizable software, it needs a module, or a node, to communicate with and send/receive data. The WiFly RN-XV is a tiny wifi device that can sample sensor data, receive other data on its serial port, connect to a router and even upload data to a remote website. Alternatively, it can be set in ad-hoc mode for intranet communications. This mode was useful as it became my only way to interface with the device for initial configuration as well as subsequent ‘fixes’, when the module would not respond to regular telnetting. (Teraterm, another computer serial communication program, is recommended and provided by the manufacturer. However, since it is a windows program, and I use Linux, I decided to use the ad-hoc mode instead.) The image below shows the wifi module with the incoming 3.3V power jumped to pin#8, which forces the module into ad-hoc mode and allows a telnet connection to the module on its own “Wifly-GSX-f4″[Note: the last two numbers “f4” are specific to each module and correspond to the modules last two MAC address numbers] network at IP address 169.254.1.1 on the default port 2000.

"wifly in ad-hoc mode"
WiFly RN-XV in ad-hoc mode. Note the jumper putting 3.3V on pin # 8, and christmas tree lighting pattern on the LEDs

Network Configuration

The manufacturer provides documentation under the ‘Resources’ header on its website here, and I needed to go through the user manual thoroughly and extensively in order to understand how to configure the module. The datasheet also was necessary to determine each pin’s function. Although the module is capable of providing many different features, I needed to choose the right ones in order to fit it into my own network. A decision had to be made: should the wifi module send data over a TCP connection to the router which would then process this data and send it on, or should the module establish an HTTP connection and post directly to a remote web server? Since I was having trouble finding a small email program for the router that would send file attachments (in this case, it would be the jpeg), I decided to try HTTP client mode on the wifi module. The code required, was:

set wlan ssid ----// this sets the module to connect to my network(insert name) only
set wlan phrase ---- // this sets the local wireless network password, in my case with WP2 security
set ip proto 18 // this puts the module in http as well as tcp mode
set dns name ---- // this would be the web address of the remote web server
set ip remote 80 // this is the remote web server's incoming port, usually 80
set com remote GET$/post.php?DATA= //this sets up the URL request to remote server
set option format 3 // this sends a header and data converted to ASCII in the http POST
set sys autoconn 1 // this tells the module to make the connection on wake up
set uart mode 2 // this tells the board to wake up on incoming serial data
set comm size 1460 // this ups the flush size to the maximum, for higher throughput
set comm time 500 // this increases the flush timer to wait longer for incoming bits

I tested this setup with posttestserver.com, a free testing server offered by Henry Cipolla, and some of my first test posts can be found in my directory here. Further thanks to Mitch at Roving Networks, for his helpful technical support in the WiFly configuration.

Sensors

Since the sensor sampling pins on-board the wifi module are analog only, my digital temperature sensor would have to be regulated to an extra digital pin on the JPEG trigger; however, when my other order arrives, I can attach the analog temperature and humidity sensors directly to the WiFly. But for now, the WiFly is set to send out data via HTTP on incoming data on the UART Rx pin.

Camera + Trigger
Trigger

It is the JPEG Trigger from Sparkfun which controls and processes the camera and its data. Although it is possible to go through the hardware details of the Linksprite JPEG Camera and communicate with it directly through another microprocessor, it made much more sense to invest in a microprocessor + board that was already set up for this camera. The $30 price tag was well-spent: on the trigger came an ATmega 328p processor, UART serial connections, ISP connections, mini-plug for a battery supply, trigger pin area, microSD card holder, starter configuration (sketch + needed libraries), and, of course, a separate 4-pin connection for the camera itself. Since my LiPO battery had not yet arrived, I had to find another way to power the board. There are two pin spaces next to the battery plug for ground and up to 5V. Since the trigger takes 0-5V power input, which it uses to power the camera as well as itself (there is a voltage regulator on board as well), as long as I could find an old wallwart ~ 5V, I could at least get started with testing the trigger with camera function. Fortunately, I had an old 5V power adapter available. Likewise I found an unused 2GB microSD card in my stockpile of old electronics, also needed not only since the sketch shipped with the trigger requires an inserted card before functioning, but also because there is no other way to check if the camera is working without a)uploading a new sketch that will send the jpegs out somehow, or b) using the Linksprite camera evaluation tool. [Note: this evaluation tool is not freely available on the Linksprite website without registering; however, I found this link from one of their distributors for the download.] I needed to update the sketch in order for the jpeg trigger to send the image out, via UART serial, as well as save it onto the SD card. The following line was inserted into the code (right before the line that prints the data to the memory card):

Serial.print((char)response[i], BYTE);

Later, I plan to add code that provides a way to trigger the camera remotely via an incoming signal on the UART serial port.

Similarly, I wanted the temperature data from the Maxim DS18B20, which is a digital sensor, to be read by the jpeg trigger. There were no digital input pins set up on the board, so I had to find unused ones on the microprocessor to solder a connection. After emailing Sparkfun tech support, I found the pin map and the ATmega layout for this specific version (SMD) of the 328P, which basically clarified that two unused digital pins (#7&8), corresponding to PD7 and PB1 on the hardware, can be called on to read the digital input from the sensor. I soldered to pin PD7, as can be seen in the image below.
"digital pin on the AVR328P"
JPEG trigger with extra connection for a digital input

And for this extra functionality, I added code to sample the digital pin 7 and send out the data via serial every ten minutes.

The bildr tutorial, the arduino OneWire documentation, and the mbed example were very helpful in producing the required code. In fact, my code is simply a mixture of those codes inserted into the jpeg trigger sketch, with small changes, such as converting the output degrees to Fahrenheit and changing the sensor sampling rate.[A note about uploading to the jpeg trigger: this board does not have the regular mini-B usb connection, so I had to upload through the UART serial pins. This took three days of repeated failed uploads (avrdude not communicating…) until I stumbled on a sequence of steps that worked: add the 5V power to the serial connection, turn the board’s switch on, and hold the reset button until just before the sketch size pops up on the monitor. If this fails, the only other recourse would be to utilize the 6-pin ISP connection with an AVR programmer.]

Camera

The LinkSprite infrared jpeg camera with UART connection is on a small board about 1.5″x1″ big. A few test pictures are shown in below. For a 160 x 120 pixel picture the quality is not bad! The color pictures are decent, and the infrared turns on when needed. The pictures are compressed by the camera itself, and turn out to be about 12.5kB each. The size is important for later adjustment of the wifi module’s configuration for packet transmission and throughput.

"ceiling"

"ceiling #2"

"ceiling #3"

"ceiling + me"

"scary me!"

"infrared me"

Initial Test Pictures from Linksprite camera

Bringing it all together…

Referring back to the diagram in the Introduction, the camera is connected to the jpeg trigger board, which is connected for bi-directional flow as well to the wifi module. On incoming data (after a jpeg is triggered or a sensor sample is read), the wifi module wakes up and sends this information to the router.  The picture below shows these parts wired together.
"three parts"
Wifi Module, JPEG Trigger, and Camera working in unison.

With all three parts of the node functioning, the next step was figuring out how to pass this information (in this case, a picture, and/or a temperature reading) back to the source node (i.e. the router) or even posting the data directly to a remote site. Posttestserver.com, mentioned above, was very useful testing, but it would be even better to have the data posted to a personal page or website. Twitter and Google Docs accept posts with special authorization protocols, but I was hoping to find a way to have more control over incoming posts and processing of those posts. Pictures of my outside gate are better kept private, and I would like them sent to my phone and/or email account. A few of the ideas that came up:

  1. use existing pages online to serve a script to process incoming http information
    • issues: most free websites won’t allow own CGI’s, since http POST is not a secure protocol
  2. set up a personal website to accept http POSTs
    • issues: can a blog post be made through http POST? how to configure a website to do this?
  3. set up my own webserver
    • issues: have to learn how to set up on router (is there enough room?) and have to learn first how to do it
  4. find another way…

I have yet to find the best solution, but idea #3 seems the way to go, for a few reasons. First, my situation is particular — I have regularly incoming sensor data that I want processed into a webpage, graph, or readout of sorts, but I also have randomly incoming jpeg files that should be emailed directly to me. If the router can accomplish both these tasks, then it should, and the processing will be local and possibly more robust, since there is less chance of transmission loss. Secondly, I could avoid remote website security protocols. And finally, I could make full use of OpenWrt, which has given me the opportunity to upload my own mini-programs for extra functionality.

Having said that, I tried idea #2 and was able to have incoming data sent to my email through use of a hosted php script.  The php site here and here (check out script ideas in the comments!) and this guide got me started — with others’ code offered online I came up with:

<?php
//function multi_attach_mail($to, $files, $sendermail){
// email fields: to, from, subject, and so on
$to = "myemail@mymail.com";
//$subject = date("d.M H:i");
$subject = "from thenameofthisfile.php";
//$from = "Files attach <".$sendermail.">"; 
//$subject = date("d.M H:i")." F=".count($files); 
$from = ${"_" . $_SERVER["REQUEST_METHOD"]}['from'];
//$message = date("Y.m.d H:i:s")."\n".count($files)." attachments";
$files = $_FILES;
$message = ${"_" . $_SERVER["REQUEST_METHOD"]}['message']."\n";
//$message .= date("Y.m.d H:i:s")."\n".count($files)." attachments";
$message .= date("M.d, Y")." at ".date("h:i:s a")."\n".count($files)." attachments";
$headers = "From: $from";
 
// boundary 
$semi_rand = md5(time()); 
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; 
 
// headers for attachment 
$headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; 
 
// multipart boundary 
$message = "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n"; 
 
// preparing attachments
for($i=0;$i<count($files);$i++){
    if(is_file($files[$i])){
        $message .= "--{$mime_boundary}\n";
        $fp =    @fopen($files[$i],"rb");
    $data =    @fread($fp,filesize($files[$i]));
                @fclose($fp);
        $data = chunk_split(base64_encode($data));
        $message .= "Content-Type: application/octet-stream; name=\"".basename($files[$i])."\"\n" . 
        "Content-Description: ".basename($files[$i])."\n" .
        "Content-Disposition: attachment;\n" . " filename=\"".basename($files[$i])."\"; size=".filesize($files[$i]).";\n" . 
        "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
    }
}
$message .= "--{$mime_boundary}--";
//$returnpath = "-f" . $sendermail;
$ok = @mail($to, $subject, $message, $headers);//, $returnpath); 
if($ok){ return $i; } else { return 0; }
//    }
?>

This script receives a http POST or GET request and sends an email to my account with the name of the script in the subject line, the website host’s default emailer as the ‘sender’, and the message with a timestamp and number of attachments. The free http tool at hurl.it was great for testing; afterwards I could get the WiFly module to connect to this script to send out an email as well, but was unable to receive usable data, as of yet. Still working on that step…to be continued….

6 Responses to wireless home sensor network, part I

  1. Eric says:

    Awesome! :) I’ll have to look into the wifly; I just got some TMP36 sensors because I am curious about input & output temps on my boiler; I was going to hook it to an arduino but then it’s a network cable run or an expensive wifi shield… I’ll look into the wifly, maybe it’s all I need!

    -eric

    • admin says:

      The thing about the Wifly is that it takes analog sensor inputs, I believe only 0-3v. For this reason I put the digital sensor on the trigger board. But the TMP36′s are analog so you should be good. There are up to 6 inputs or so, depending on how you configure the device. The hang up for me became getting my UART data out, but this should be easy for you with small number of bits. The jpegs require ~11 packets, so I (think I) have to learn about sockets before I can get any farther with this project. I don’t have a programming background so it might take me a while ;).

      • Eric says:

        Yep the TMP36 would be happy at 3V or so. I wish the wifly had a little nicer form factor, but I understand that it’s designed to go into an xbee socket. Maybe to break things out nicely an xbee carrier board or shield would be handy.

        It’s always the physical hookup & packaging that I get hung up on in the end.

        • admin says:

          Ah yes it’s too bad the antenna is sticking out the opposite side of the headers, if you’re using it without a board. But smaller is better and for your application it can definitely be a standalone device, and you could always just make some sort of adjustment for antenna, say a hole where the antenna could stick out or wire it to loop around the edge or something.

  2. Pingback: Syncing a Halo Nixie Clock via WiFi | Garantía Nula

  3. SanUSB Laese says:

    Sketch Arduino for Wifly RN-XV modem configuration without Wifly library and
    with front-end: https://dl.dropboxusercontent.com/u/101922388/WiflySanUSB.

Leave a Reply

Your email address will not be published. Required fields are marked *