Friday 30 March 2012

Wireless sensor node - software (15)

My home wireless sensor network has now been operational for just over a week. It currently only consists of two nodes.

A base station.


A single wireless RF sensor.


In my last post I was concentrating on getting the base station constructed and deployed. Since then I have been focusing on enhancing the software which runs on the base station and the software which I am currently running on my own PC to download the temperature readings. 

The base station exposes a command driven interface over Bluetooth. The long term plan is to use a raspberry pi to download readings in real time. However, in the mean time I have programmed the base station to write readings to file every hour. These files are read over the base station command interface by my desktop application. 
 
The Bluetooth interface currently accepts all of the following commands (along with some other debug related commands):
  • set_time_<n> - this allows the real time to be set on the base station. No readings are recorded until this has been set.
  • ls - List the files in the root of the SD card.
  • cat <file> - Return the contents of a file.
  • rm <file> - Delete a file.
  • rm * - Delete all the files.
These are issued by my desktop application to fetch all of the recorded data and graph it.


My intention is to upload these readings to https://pachube.com/ but I haven't got round to writing the code to do this yet.

The full code for my windows application is available here.

Monday 19 March 2012

Wireless sensor node - enclosure mark 2 (follow up) (14)

At the end of my last post I had packed all of the components of my base station into an enclosure and had everyone working. Almost.

The one issue I found was that whenever I was connected to the base station over Bluetooth, the base station was unable to receive temperature readings over the 315MHz RF link.

This is what the setup looked like when it didn't work.


In the end I posted to the Arduino forums and spoke to some friends about the issue and concluded that the Bluetooth RF must be interfering with the actual circuitry of the 315MHz RF receiver. My first idea was to try and setup some kind of electromagnetic shielding around the 315MHz RF receiver module. However, before I began working on this I decided to try simply moving the Bluetooth module further away from the 315MHz RX module.


And now it works! The extra ~5cm of distance is enough to avoid whatever interference was previously taking place.

Sunday 18 March 2012

Wireless sensor node - enclosure mark 2 (13)

My previous attempt to pack all the parts of my base station into an enclosure ended in failure. I previously attempted to find an alternative box on the Hobbycraft website but was underwhelmed by the 6 search results in their online store. I was therefore not expecting much when I went to my local Hobbycraft store this weekend.



I was actually really impressed! Hobbycraft had 2 entire rows of boxes of various sizes and colors! I bought three sizes - a medium one for storage, a smaller one to hold my base station parts and the smallest one to potentially hold a wireless sensor node. It turns out that my previous search results were simply the result of a poor query. I had searched for "plastic box". If I had searched for "really useful box" I would have found 100 products! The full range of really useful boxes can be seen here.

I spent some time re-arranging my breadboards and wiring and produced the following circuit which fit neatly in the base station box. The components here are as follows.
  • 5V 16MHz Arduino Pro Mini on the left inserted into a small breadboard.
  • USB mini breakout board for power on the bottom. This is attached to the box by four screws and I cut a hole in the side of the box to allow a cable to be plugged in.
  • SD card breakout board with 2GB card in middle.
  • 315MHz RF receiver on the right.
  • Bluesmirf silver Bluetooth module in the bottom right.
This is all contained in a 0.35L Really Useful Box.




To work with the base station over Bluetooth I installed a new Windows Serial client - Termite. After powering on my base station the first thing which my code requires is that I set the real time offset. This approach allows me to record a reasonably accurate time for sensor readings without needing a real time clock module. To set the time I have been using the Epoch Converter page. I use the results of this page to construct a command to send to the base station e.g. set_time_1332111967. Once this is done the base station successfully receives a reading every 5 minutes from my wireless sensor node. Yay!

Unfortunately I did hit one problem. For some reason my base station seemed unable to receive any sensor data while I was connected over Bluetooth. This surprised me as the Bluetooth frequency is 2.4GHz and I therefore don't expect it to interfere with my 315MHz transmitter on my receiver.

Thursday 15 March 2012

Wireless sensor node - getting started with an SD card (12)

A couple of months ago I bought an SD card breakout board. The intention was that this would allow my Arduino base station to log to memory card to provide a persistent record of the sensor readings. However, apart from soldering on some male headers, I haven't done anything with the SD card breakout until now.

To prepare for writing some code to use the SD card I assembled a neat new layout on the breadboard attached to my Arduino Uno. 


The next step was to write code to use the SD card. I used the Lady Ada tutorial to get started. I used the CardInfo sketch to validate that I could access the SD card and the list files sketch to demonstrate using the file system. 

With this complete I set about integrating the SD card code into my wsn_arduino sketch. This seemed fairly straightforward until I tried to actually use the code at which point I started hitting mysterious crashes! :(

It turns out that the SD card library is a memory hog and I was already running low on RAM before adding the SD card code. I didn't think my existing code was using much RAM until I found out that string constants e.g. those used in Serial print statements are all stored in RAM! Argh!

Reducing Memory Used by String Constants

Firstly, it is important to be able to measure the amount of free memory so that we can see how badly/well we are doing. This can be done using the FreeMem method from SdFatUtil.h

  #include <SD.h>
  ...
  Serial.print("Free RAM: ");
  Serial.println(FreeRam());

So what can we do to reduce this memory usage? The answer is to use the PROGMEM keyword. This instructs the compiler to store a variable in the much larger program memory space. However, using the keyword initially looks quite awkward. 

The article describing its use suggests that you store strings in explicit variable and copy them into a RAM buffer before use. This is really unwieldy when you just want to print a string to the console!

The solution is to use the PSTR macro in the avr/pgmspace.h header. This has the following definition. 

  #define PSTR(s) ((const PROGMEM char *)(s))

This marks a string constant for storage in program memory without having to use a separate variable. However, you now need to use a different print method to access the string. Conveniently the SD card header SdFatUtils.h has just what we need in the form of PgmPrint and PgmPrintln.

  #include <avr/pgmspace.h> 
  #include <SD.h>
  ...
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam());

The other method which I needed to use was one from pgmspace.h.

  strcmp(stringData, "dbg_fls_f")

becomes

  strcmp_P(stringData, PSTR("dbg_fls_f"))

The result of using PgmPrint and strcmp_P+PSTR for my sketch was the following:
  • Free RAM: 393 (Before)
  • Free RAM: 925 (After)
A couple of other points to note:
  • It is vital that all opened Files are closed when you are done with them as each one takes up ~68 bytes of memory while open. 
  • Arduino 1.0 includes support for a new F() macro which allows you to use Serial.print directly. This looks like the following.
  Serial.print(F("string"));

As far as I can tell this has the same effect as using PgmPrint. The advantage is that F() is included in the base Arduino headers whereas PgmPrint is only available in the Sd library header. I have stuck with PgmPrint as I slightly prefer the shorter syntax.

SD vs SdFat

When I started out this article I was following the Lady Ada tutorial which pointed me at the SD library. Unfortunately I ended up hitting a bug where I could both list files and write to a file but listing files after writing to a file didn't work. This prompted me to investigate the SD library a bit further and properly understand that it was acting as a wrapper for the SdFat library.

SdFat has been updated more recently than SD and comes with a better range of examples. For both of these reasons I switched my code to use SdFat and have subsequently managed to get everything working nicely.

Tuesday 13 March 2012

Wireless sensor node - enclosure mark 1 (11)

I got the plastic enclosure which I ordered and had a go at fitting in all of my base station components. Sadly the results were not ideal. It turns out that I had been overly optimistic about the required dimensions. The following picture shows that I was almost able to squash all of the components into the box but there was no way the lid was going to fit on properly.


I wasn't helped by the fact that the enclosure turned out to have plastic headers inside. 


This reduces the available space even further as I just want to stick a breadboard onto the bottom of the box! I was able to remove these by simply crushing/pulling them off with pliers and sanding it down.
 

The main thing which I have learnt from this is that I need more space in my base station enclosure and I really need more breadboard space to make a neater layout. To this end I have bought a new Arduino Pro Mini (so that I can solder male headers onto it), a tiny breadboard to hold the Pro Mini and a new mini USB breakout (which will also get male headers for use directly on a breadboard) board.

Sunday 4 March 2012

Wireless sensor node - enclosures (10)

I now have all of the basic hardware prepared to allow me to deploy my wireless sensor network. However, I still need to work out the best way to package the various parts.

I have ordered a couple of plastic boxes which I am planning to use to package my nodes. In particular, I want a plastic box to put my base station in so that I can screw down the usb breakout board. One of the boxes should be a perfect size to contain the base station. The smaller box will contain a wireless sensor node.

However, in the mean time I decided to try my hand at making a cheaper enclosure out of some red cardboard which I already had at home. I drew the following template using Inkscape.


The source svg file is available here. The only joint which requires glue is the tab on the left. The top and bottom are designed to be folded in on themselves without glue.

I was quite pleased with the results.


This is now sitting on top of my kitchen cupboard broadcasting the temperature every 5 minutes. I don't have my base station setup yet but since the sensor node has an expected battery life of over a year I have plenty of time to deploy the base station!

There are two main next steps:
  • Sort out the base station enclosure.
  • Write more code on the base station to log a history of readings, spot when readings are missing and expose this information over the serial port.