Wednesday, January 30, 2013

Transparent serial emulation for the RFM12B radio module

Introduction

For the AuroraWatchNet magnetometers that I am developing I currently use the Ciseo XRF radio module. They are based upon the pseudo-standard XBee footprint, operate at 3.3V and provide a UART interface to the microcontroller. They are easy to use but I have found the range is not always sufficient, typically limited to 60 metres of free space plus one exterior wall/window. Another commonly-used radio module is the HopeRF RFM12B transceiver, as used on the JeeNode. The RFM12B also operates at 3.3V but features an SPI interface to the microcontroller. It is available as a 2mm pitch surface-mount module, or as a 12 pin 2mm pitch DIP package.

As my Calunium v2 microcontroller development board can be fitted with a RFM12B radio module I naturally wanted to compare the performance of the RFM12B and XRF. Initial testing of the Hope RFM12B gave a usable range of 150 metres of free space after transmission through one exterior wall/window. Some of the additional range is due to using the 433MHz version of the RFM12B compared to the 868MHz operating frequency that the XRF defaults to. The range measurements were not very scientific and further work is required before meaningful conclusions can be drawn regarding the comparative ranges. However these initial results have encouraged me to investigate replacing the XRF by the RFM12B, particularly as it is both cheaper and uses less power. A comparison of the basic specifications can be found at http://blog.homelabs.org.uk/wireless-connectivity/.

As I have already deployed a few magnetometers using the Ciseco XRF module I would like to to use the RFM12B as a serial device. This would enable the existing firmware to be used with minimal changes. It would also allow the possibility of having a single firmware support both XRF and RFM12B modules.

Serial emulation

I have created a serial emulation layer for the RFM12B by deriving a class (RF12_Stream) from the Arduino Stream class. Text or binary data can then be read from or written to the RFM12B in exactly the same way as the standard Serial port. Since it is a Stream object the Streaming class (which overloads the >> and << operators) can also be used with RF12_Stream. The RF12_Stream class automatically breaks up the data to be transmitted into short packets which are sent using the Jeelab RF12 library. ACKs and retransmissions are employed to prevent losing data from dropped packets. A packet number is included to prevent duplicated data, which could otherwise occur for the case when the ACK is not received and a packet is retransmitted. The class keeps track of the number of packets sent and received, and the number of retransmissions, data which may be useful to identify the optimal channel on which to operate.

The begin() function takes different parameters to Serial.begin() and it returns a logical value to indicate whether the RFM12B has been found on the system. The user is required to call the poll() function periodically so that outgoing packets are sent and received packets processed. These are the only differences compared to sending data to the standard Arduino Serial port.

Source code for the RF12_Serial emulation can be found on Github, https://github.com/stevemarple/RF12_Stream; it is released under the MIT license. An example sketch is included which echoes data between the Arduino serial port and the RFM12B. When compiled for the ATtiny84 this sketch is less than 8kB so I am hopeful it can be used on the RFM12B to Raspberry Pi expansion board designed by Martin Harizanov. AsyncDelay, https://github.com/stevemarple/AsyncDelay, and CircBuffer, https://github.com/stevemarple/CircBuffer, are also required.

Calunium uses INT2 for the interrupt from the RFM12B which is not supported by the JeeLabs version of the RF12 library so I am currently using a modified version. Source for this version is also available on Github, https://github.com/stevemarple/RF12. It is intended that RF12_Serial should work with both the original RF12 library and my version.

Single firmware to support RFM12B and XRF

By utilising the return value from the RF_Stream begin() function it becomes trivial to produce a single firmware which can support either the RFM12B or XRF radio modules. The trick is to create a Stream reference which is set to either Serial (for the XRF) or to rfm12b. The RFM12B_autoselect example sketch illustrates this concept.

How does it differ from RF12sio?

The RF12sio library overloads the << and >> operators so that packets can be constructed and processed easily. The user is still responsible splitting the data into packets. RF12sio is not derived from Stream so it is not possible to use the Stream pointer trick shown in the RFM12B_autoselect sketch.

Credits

Thanks to JeeLabs and JC Wippler for the RF12 library and to Arduino for the standard Arduino libraries.

Thursday, January 24, 2013

How to use the Atmel ATmega1284 (non-P version) with tools that don't support it

I found out by accident there is now an Atmel ATmega1284 microcontroller, as well as the older ATmega1284P. The first I knew was when I tried to upload the bootloader and avrdude warned of a signature mismatch:

avrdude: Device signature = 0x1e9706
avrdude: Expected signature for ATMEGA1284P is 1E 97 05
              Double check chip, or use -F to override this check

Correcting the device didn't help, avrdude doesn't recognise the ATmega1284. That could be fixed easily by creating a custom entry in $HOME/.avrduderc. I didn't bother with that since avr-gcc doesn't support the ATmega1284. At this point I was slightly worried as I had ordered a large quantity of ATmega1284 instead of the ATmega1284P.

A work-around

Fortunately there is a work-around. The two microcontrollers are essentially identically except for some small electrical differences relating to power usage and the last signature byte. Therefore code compiled for the ATmega1284P will run on the ATmega1284. If you are using avrdude to upload just add the -F command line option to force the signature check to pass.

If you use the xboot bootloader you should have no further problems after installing the bootloader since xboot doesn't check the signature bytes. Users of the Optiboot bootloader are probably not so fortunate; I believe the signature is checked - I haven't tested it since I'm now using xboot on all of my Calunium development boards.

Sunday, January 13, 2013

Magnetometer progress report

About AuroraWatchNet

I am developing a simple, low-cost, battery-powered magnetometer for auroral alerts and citizen science. It is intended to be wireless to allow easy installation, a unique feature as far as I am aware. The magnetometer uses my own Calunium micro-controller board, which is an Arduino clone based on the ATmega1284P micrcontroller. Data is sent via a radio link to a Raspberry Pi base station which will then forward the data to AuroraWatch UK. I am hoping to deploy a network of such magnetometers in 2013 to enable AuroraWatch UK users to contribute data to improve the service. If you want to track the development then follow @aurorawatchnet on Twitter. 

The first AuroraWatchNet magnetometer is currently running in my garden. The environment is not ideal as I can see disturbances from cars and even the garage door being opened but it is convenient for testing and representative of what to expect from user-contributed data. I have been comparing the results from our SAMNET magnetometers with the AuroraWatchNet prototypes and generally the results are very encouraging given the difference in cost between the two systems. Now I can plot the AuroraWatchNet magnetometer data in the standard AuroraWatch UK style, using the same Octave code. Below is a comparison of today's plots. 

AuroraWatch UK

The data is taken from SAMNET's Lancaster magnetometer. The X axis is time and the Y axis shows the magnetic field strength in the direction of magnetic North (H component) in nanotesla (nT) relative to an unrecorded baseline. This exact plot appeared on AuroraWatch UK. We would normally expect cleaner data but our Lancaster site has recently been experiencing some interference.

SAMNET data from Lancaster, as used by AuroraWatch UK

AuroraWatchNet test magnetometers

The plots below correspond to the same time interval as the plot above. The first plot is from my garden magnetometer.

AuroraWatchNet data from near Lancaster.

The Y axis again records magnetic field strength but this time it is the absolute field. This magnetometer is operating in power-saving mode, turning off the sensor when not needed. This slightly increases the noise level but I hope will give one year of operation from two D cells.

Another AuroraWatchNet magnetometer has been deployed almost adjacent to the SAMNET magnetometer we already use for AuroraWatch. In this system the magnetometer sensor is continually powered, resulting in reduced noise levels. The alignment with magnetic North is only approximate. 


AuroraWatchNet data from the Lancaster University field station.

Conclusion

The AuroraWatchNet magnetometers are sufficiently sensitive and stable to make useful contributions for auroral detection and citizen science. My experience with the garden magnetometer suggests that in many cases performance will be limited by the noise at the site, rather than the magnetometer.

Thursday, January 10, 2013

UART-USB converter for mixed 3.3V/5V operation


For some future projects I have in mind I would like to add a USB interface to my Calunium development board, rather than using the Sparkfun FTDI basic breakout board that I have been using. One of the key features is that it should work seamlessly with the jumper-selectable 3.3V or 5V operation offered by Calunium v2, which is most easily accomplished by a self-powered design; auto-reset is a bonus.

Microchip offer the MCP2200 USB interface in a choice of packages including a 20 pin SOIC package which is very convenient for home assembly of PCBs. I found conflicting information about the MCP2200 so I prototyped the above circuit to check that mixed 3.3V/5V operation was ok. VUSB (pin 17) is permanently connected to 3.3V so that the USB signalling levels are always correct. The VDD supply pin is connected to IOREF on my Calunium board, which is either 3.3V or 5V, depending on the position of the voltage selection jumper, ensuring that the logic levels for the MCP2200 match those used by the microcontroller. I also wanted to test whether the MCP2200 would auto-reset the microcontroller. The MCP2200 doesn't have a DTR output pin which is how modern Arduinos reset the microcontroller for uploading a new sketch. Fortunately the MCP2200 does have an RTS output, and as that was the method used by older Arduinos I connected that to /RESET via a 100nF capacitor.

After building the circuit and connecting it to my Ubuntu 10.04 Linux computer the MCP2200 was immediately recognised, I used the dmesg command to see this. Ubuntu automatically created the /dev/ttyACM0 device file, no configuration changes were needed at all. Using gtkterm I was able to toggle the state of the RTS pin. I then hooked up the circuit to one of my Calunium microcontroller boards and was able to upload sketches without needing to press the reset button, in both 3.3V and 5V operation modes. I haven't tested this from Windows but from what I've read on the Microchip forum I suspect it won't work due to deficiencies in the Windows driver.

The datasheet suggests that a ceramic resonator can be used instead of the crystal and load capacitors. I found it did work even though the resonator's frequency tolerance was 0.5%, not 0.25% as required by the USB specification. As I can't source any resonators which meet the specification I'll be using a 12MHz crystal.

The MCP2200 wasn't my first choice; the obvious part was the FTDI FT232RL, although I had reservations about working with an SSOP package. Further investigation revealed that 3.3V operation requires an external crystal, but to use one isn't straightforward. On first use the FT232RL must be powered from >= 4.0V and a custom utility (not openly supplied?) is needed to select the external crystal. The standard MPROG utility cannot be used for this. I am aware that the FT232RL could be powered from the USB 5V supply but I am not a big fan of powering devices simultaneously from both internal and external supplies. One of the future projects is to replace hardware which is powered from multiple sources and is very susceptible to damage from being powered up/down incorrectly.

In conclusion, this is a very useful USB converter for Linux users and for final designs. Windows users who wish to regularly upload new firmware via a bootloader may find it less useful.