Today I’m going to share my designs for a wireless sensor network build using Felix Rusu’s awesome Moteino R3 platform. My network measures light, temperature and humidity in my office and I plan to use it to help me figure out how to make the temperature in here more manageable in the summer.
Enter the Moteino!
The Moteino is a low cost Arduinio-compatible ATMega328 chip bolted onto a HopeRF RFM69 radio transceiver. I’ve concluded that this is a much better platform than the Ciseco XRF for sensor networks after a few weeks of evaluating both. Moteino is a really ideal platform because:
- The Moteino works out of the box the way you expect it to
- Is easy to integrate into a breadboard with 0.1″ spacing
- The wireless platform is optimized for sensor applications, not serial poirts
- Its much better documented than Ciseco’s products (strange too, since Ciseco is a multi-employee company and LowPowerLabs is apparently being run out of a suburban home in Detroit.)
- Shipping time is nice and quick from Detroit, MI
- Everything you need – FTDI port, power regulator, status LED is already on-board
- More pins!
Felix hand-assembles the Moteino’s at home — the build quality is remarkable.
Here is a photo of the front and back side of the Moteino, courtesy of Felix’s website:
Prototyping the sensors
To start with my project, I assembled a protoboard with all of the sensors I planned to hook up so I could be sure everything works electrically. Included are the following sensors:
- A Modern Devices Wind Sensor (a hot-wire thermal anemometer)
- A TSL2561 digitally calibrated lux sensor (by Adafruit)
- A 1M + 100K Ohm voltage divider for measuring battery voltage
- A Dallas one-wire thermometer (for evaluating it for the future)
- A BMP085 barometer / thermometer (by Adafruit)
All of this fits onto a half-size breadboard.
I wrote the control code to be modular, so that depending on the “personality” of the sensor, different libraries would be automatically linked into the sketch and transmitted. If the library is not needed, the headers are not pulled in to keep the code size manageable. The nodes emit helpful debugging information to the serial port if desired. I also added a special “LOWPOWER” mode puts the AVR and its integrated radio into a very low power sleep state until it is woken by the watchdog timer.
Each personality for the sensor platform is set with a set of C pre-processor definitions like so:
My window watcher
In addition to the prototyping board, I also designed an integrated “window watching” sensor that can detect outside light levels and compare them to indoor light levels. Its intended to be mounted on a window. When the blinds are closed, they reflect back more light than when they are open, letting me measure how open or closed they are.
This window watching sensor came out fairly well considering I’ve never made anything significant with a soldered breadboard before.
Closeup of the front:
Closeup of the front with the Moteino removed:
I’m using a raspberry PI as a gateway to the internet for my network. As you can see below, the wiring is very simple — just power, ground and Moteino’s D3 pin to RXD.
I originally planned to use a Arduino Yun as my gateway. After hacking with it for a few days I gave up and switched to the Raspberry Pi. The Yun does not really ready for such a task — perhaps the hardware or software is not yet mature. I kept running into unexplained crashes and missing bytes, probably a combination of the Yun missing a hardware serial port UART and some flakiness with the Bridge library that lets the Arduino interface with the chip that runs the Linux OS. This is really too bad since the Raspberry Pi is overkill for data logging and has a much less stable filesystem.
The communication protocol between the sensor nodes is dead simple and includes metadata that will maximize the utility of the data for analysis. Each packet is a comma-delimited line of text with fields like this:
The fields are:
- 1st character: R for reading, C for command, I for info
- A device specific sequence number for the message
- The node name of the sender
- A timestamp from the sender (usually # of milliseconds since start)
- The name of the sensor
- The sensor reading
- The units of the reading
- An optional memo field
When the packet is received, code on the raspberry pi gateway adds a local timestamp, the RSSI and the sending node ID.
pi@raspberrypi ~/sensornet $ tail mainlog.csv 2013-10-25 10:51:50,R8354,Proto,1576920,LUX-Broad,1935.00,rawb,,-56,99 2013-10-25 10:51:50,R8354,Proto,1576920,LUX-Broad,1935.00,rawb,,-55,99 2013-10-25 10:51:50,R8355,Proto,1576991,LUX-Infra,729.00,rawi,,-55,99 2013-10-25 10:51:51,R8356,Proto,1577071,BMP-Temp,22.98,C,,-55,99 2013-10-25 10:51:51,R8356,Proto,1577071,BMP-Temp-F,73.364,F,,-55,99 2013-10-25 10:51:51,R8356,Proto,1577071,BMP-Temp,22.98,C,,-55,99 2013-10-25 10:51:51,R8356,Proto,1577071,BMP-Temp-F,73.364,F,,-55,99 2013-10-25 10:51:51,R8357,Proto,1577176,BMP-Pressure,101297.00,Pa,,-56,99 2013-10-25 10:51:51,R8357,Proto,1577176,BMP-Pressure,101297.00,Pa,,-58,99 2013-10-25 10:51:51,R8358,Proto,1577893,MDWIND,558.00,raw,,-59,99
The advantage of this format is that it can be easily loaded into a database or a charting package and used out of the box. Its very easy to filter, cross-tab etc. Eventually, I plan to have the receiving script insert directly into a database, in which case this format will still be useful as a way of creating “archives” of sensor readings.
Using a charting package called Tableau, I pulled some interesting charts. Tableau is one of the very best data visualization packages I know, and it an essential tool in my daily work at PatientsLikeMe. Here you can see the pattern when the window shades are opened or closed. The dip where the top line and the middle line spread apart is the point where the shades were open.
Another example, showing the Dallas, SHT15 and BMP085 each tracking my office temperature. (Note: the SHT is closer to my LCD display so is generally reading higher values.)
Getting the data from the serial port on the Motetino to the Raspberry Pi is a simple task, however I invested in a somewhat unusual design for the gateway script. I want my sensor network to have the option of bi-directional communication, meaning that it should be possible for the Raspberry Pi to send out commands and information back out to the nodes. One use of this might be to enable a wall display with the temperature and light levels. This means that the script must handle the back and forth traffic between the serial port a TCP connection and the file system. I decided to use a Perl script with a select statement to handle the multiplexing, a somewhat complex solution but provably the most CPU efficient mechanism at least in POSIX UNIX. In theory, a solid Pyhon coder could probably figure out how to do the same thing with threads, but I am not a full-time developer anymore and never learned Python.
Getting the source
If anyone writes to me, I’d be happy to share the code for all of the above. Its also available in my GIT repository here although its constantly evolving and not in any kind of “release”. I’m not really sure who reads this blog or if anyone is interested in sensor networks the way I am, so I’m holding off making a formal dot release.