Sunday, 5 February 2012

Wireless sensor node - background rx (6)

I have started to think a bit more about deploying my wireless sensor network. My plan is still to deploy multiple cheap ATtiny85 based RF transmitting, battery powered sensor nodes. These will talk to an Arduino base station which will receive the readings. 

The base station needs to save the readings to an SD card, allow bulk uploads over Bluetooth and will possibly in future drive a screen. None of these things will be possible if the Arduino has to spend all its time blocked listening for readings from the sensor nodes. Therefore, following on from my last post, I decides to upgrade the Manchester library I have been using to do interrupt based RF message reception. 

I'm quite pleased with the results. The old API for receiving data looked like this. 

// This call blocks until a timeout or a message is received
// to avoid missing any messages the caller must either set no
// timeout or immediately call this method again after a timeout. 
unsigned int data = MANCHESTER.Receive();

Old API on Github.

This has now been improved to work as follows. 

// The MANRX code receives a single message in the background
// This call checks whether there is a message ready for us
// to get. 
if (MANRX_ReceiveComplete())
{
  // We extract the message
  unsigned int data = MANRX_GetMessage();
  // And tell MANX to start receiving the next message
  // in the background
  MANRX_BeginReceive();
  // Handle data...
}
New API on Github.

While working on this code upgrade I also spent some time improving my breadboard setup. I had previously wired my main breadboard to act as the RF RX and an ATtiny ISP. I then manually moved the ATtiny board onto a second breadboard which was battery powered and acted as the RF TX.

It turns out that the ISP circuit leaves a couple of pins free on the ATtiny which is just enough to run the RF TX circuit which I have been using. As a result, I was able to put together the following neat color coded setup on a single breadboard.


This is color coded as follows.
  • Yellow - GND
  • Orange - VCC
  • Black - ISP connections
  • Red - RF data connections
  • Green - RF antenna
The LED included in the breadboard isn't normally part of a circuit.but is wired up to ground so that I can connect a data output to the LED VCC and see visually the state of that data output.


To test my RF code I have to use the following steps.
  • Program the Arduino with the ISP sketch
  • Program the ATtiny with my RF TX code using the Arduino as an ISP
  • Program the Arduino with my RF RX code
Comparison with VirtualWire

Now that I have added interrupt driven RX logic to the Manchester library it is worth considering what differences still remain between the Manchester library which I am using and the more popular VirtualWire library.
  • TX - VirtualWire uses interrupt based TX to allow for non blocking message sending. Manchester does not.
  • Variable message size - VirtualWire sends a message length so the receiver can receive messages of any length. Manchester allows different message lengths but the receiver must explicitly expect to receive the same size of message as the sender is sending.
  • Checksums - VirtualWire includes a built in checksum. Manchester does not.
  • Efficiency - VirtualWire uses 4->6 bit encoding. Manchester uses 1->2 bit encoding.
  • Clock Skew - VirtualWire is more sensitive to clock skew than the Manchester library.
This final point is the reason why I really like using the Manchester code. According to section 21.4.1 of the ATtiny85 datasheet the ATtiny is shipped with a clock of 8MHz which is only accurate to ±10%. It is possible to calibrate the clock to be more accurate but it will still vary depending on temperature and supply voltage. Given that I want to use my ATtiny85s in battery powered sensor nodes across a range of temperatures it is important that I use an RF library which can handle noticeable clock skew.