- Published: Thursday, 09 January 2014
- Written by RangerBob
I've seen too many Arduino Wifi remote sensors that proudly announce their battery life measured in days or even hours. What frustrates me most is that none of them seem to have realised that the RN-171/RN-131 Wifly module many of them are using to connect to the wireless network is a 32bit powerhouse that is perfectly capable of performing and posting the measurements by itself! They are all too happy to leave the Arduino banging away in a main loop, running off a 9V battery via the linear regulator, and ignoring the perfectly capable processor on the Wifly itself. I like Arduino, but I much prefer using the right tool for the right job!
As such the object of this article is to outline a small, simple battery powered Wifi enabled sensor, with a operational lifespan in the range of weeks to months (depending on your setup) based around the Roving Networks (now owned by Microchip) Wifly RN-171 module: the RN171p-EK evaluation module. Our collected data is posted to Thingspeak using an interim translation service, but any cloud service or local database would do.
My test feed is located at: https://www.thingspeak.com/channels/8699
Now in theory, the Wifly would be perfectly capable of posting any data directly to a cloud service. In practice there are two limitations. The first is that for some reason I cannot fathom, the Wifly HTML Client mode terminates its requests with "\n\n" (linefeed, linefeed) rather than the much more typical "\r\n \r\n" (newline, newline) that pretty much everything else uses. As such many off the shelf webservers that I tried do not see the HTML Client mode requests at all, waiting for the "\r\n" that never comes then eventually timing out. Our other issue is that the data is posted in a fixed format. We have two ways we can approach this issue. One would be to create our own Server instance which we host and control (which would be perfectly OK using the Thingspeak source code, but beyond this simple project), or we can run a simple translator which takes the data from the sensor via the wireless network which is mounted where there is convenient power, and posts it in the correct format. For this excercise I took the translator option, written in python and running on a windows machine or a Raspberry Pi, but being python you could run it on pretty much anything. (Thingspeak guys - Feature request! Direct Wifly data submission please!)
Raspberry Pi Configuration
The easiest way I have found to code and play with the Raspberry Pi has been the Adafruit WebIDE system. To use this:
Download the Adafruit Occidentalis OS (see here for configuring your SD card)
Install WebIDE (Instructions Here)
Install Twisted (sudo apt-get install python-twisted)
Import the code into webIDE and then you can run or schedule it as necessary. Do not try to Visualise or Debug as webIDE doesn't seem to cope very well with the twisted libraries!
- I am a hardware guy. The software is probably not perfect and probably not the Python way of doing things. Tough. It works.
- This is for Python 2.7. Might work on 3 but not tested.
- You must have have the Python Twisted Libraries installed for this to work. I didn't fancy writing my own multithreaded server code, and the example I created is simply a small part of a much bigger project.
- The host machine needs a fixed IP address for now, and should be on the same local network as the sensors.
- Thingspeak only allows 8 data fields plus a status string to be submitted on a single channel. The Wifly module has 8 analog inputs, battery level, rssi, GPIO state, plus a lot more. As such I selected a limited subset of Battery voltage, RSSI, overall GPIO state and the 4 accessable analog sensors to log. I also populated the "Status" field with the Wifly and AP MAC addresses. You can very eaily change the translator program to submit other configurations.
Then run "python WiFlyThingspeakBridge.py" or via WebIDE.
(note: you can add --log=debug to log more information)
- The analog ADC's on the Wifly module saturate above 400mV. You must not apply a voltage above 1.2V under any conditions!
- Sign up for a Thingspeak account here.
- Sign in and go to "Channels", then click on "Create New Channel".
- Fill in the details of your channel, being sure to add all 8 available fields. Name them as shown.
- Then click "API Keys" and note down the "Write API Key" presented.
The module is configured as per the Wifly User guide. I prefer using the USB serial port, but you could perform the configuration via the Soft AP mode or Telnet.
We need to send the following commands to configure the unit:
Resets the unit to defaults. RESET must be in caps.
set wlan SSID <name of Wifi Network>
This is the SSID of the Wifi Access Point we want to connect to. Spaces must be entered as $.
set wlan pass <passphrase>
This is the passphrase of the Wifi AP.
set wlan hide 1
Hide the passphrase so it cannot be read out of the module.
set ip host 192.168.0.4
This is the IP address of the Host machine. Substitute your own.
set ip remote 88
This sets the port we want to use (88 for the posted source).
set ip proto 18
Sets TCP and HTTP client modes.
This sets the beginning of our GET string (the Wifly uses $ as a space character).
set option format 0xff
This appends the data, id, GPIO and ASCII ADC values to the header.
set opt deviceid <API_KEY>
You need to enter the Thingspeak write API key here. By using the API key as the device ID, you can have many sensors each posting to a different channel with no other configuration changes needed!
turn on sensors!!
Turn on sensor power if required.
If we are running the unit off of batteries, we really want the unit to be sleeping as much as possible, but this can make it tricky to reconfigure the unit. If there is a permanent supply, then power consumption is less of an issue and you may choose to leave the unit in run state permanently for convenience. The options are thus:
set sys auto 255
When the unit wakes, attempt a connection to the Host immediately, then go straight back to sleep once completed.
set sys sleep 5
Go to sleep after 5 seconds. If the unit fails to connect for some reason (Server not running, AP out of range), it would otherwise stay awake. This ensures it always goes back to sleep.
set sys wake 60
Wake up every 60 seconds. Obviously change this number if you want a different interval.
set sys trig 1
Wake up on serial recieve. Makes debugging easier!
set sys auto 60
Connect to the Host every 60 seconds.
The module can also wake from a number of other sources such as wake on sensor input or wake on UART. See the user guide for more details.
When you are happy with the configuration type:
save then reboot
Start the translator program now on the host machine if you haven't yet. You can launch the translator with the "--log=debug" switch which will produce a log in the launch directory and should help to diagnose any issue.
As a test, I configured one of my units to wake at 20 second intervals, take all readings, then go back to sleep. The module posted approximately 28000 datapoints over a 156 hour period (>6 days), with a 35 hour gap which was caused by a power cut to the host server (this is actaully a worst case scenearo, as the module does not return to sleep as quickly on a failed connection, as can be seen by the more rapid battery depletion over this period). The module takes approximately 1.5 seconds to perform a successful post, and 5 seconds to fail.
As the sleep mode power consumption is negligable compared to the active power (4uA sleep, 40mA RX, 180mA TX), we can get a good idea of battery lifespan in terms of datapoints by extrapolation.
If we extend the time interval to once per minute, we should get around 19 days worth of endurance ((28000 / 60) / 24 = 19.4 days).
If we extend the time interval to once every 5 minutes, we should get almost 100 days worth of endurance ((28000 / (60 / 5)) / 24 = 97.2 days).
Be aware this does not take into account power consumption of any attached sensors, nor any temperature variation which may reduce the battery lifespan somewhat. I did not disable the LED's either which would save some power (but is useful to see if it is working!).
The sleep current will start to become a more dominant effect the longer we go, but at longer intervals we can expect even longer endurance. I personally feel that at a suitably long interval (20+ Minutes) a years operation from a single set of AAA's (860 – 1200mAh) should be acheiveable. Of course if we add a rechargable battery and a small energy harvester such as a solar panel, endurance should be effectively unlimited!
I didn't cover much on sensors themselves. I leave this as an excercise to the reader. This blog has a good writeup with a similar goal, albeit with a different approach.
Once your data is in "the cloud" it becomes possible to present that data in a variety of ways. You can always just use the built in thingspeak triggers and visualisations, or you can use its powerful data API and create your own charts or data handling systems. For example, heres a simple page that presents the data in a more specific way: