Friday, 11 November 2011

Remote Sensing with XBees, Software

In order to send AT commands to a remote device, a Coordinator must be in API mode while an End Device can be in either API or AT mode. Putting the Coordinator into API mode requires updating its firmware using a USB-Serial converter and a program called X-CTU (downloadable from X-CTU requires Windows to run but it works fine in a VirtualBox, once you plumb through the serial device.

When X-CTU can see your device, read the modem parameters and firmware, change the function set to Coordinator API, and write the firmware back to the device. (If the firmware version on the chip does not support the Coordinator API function set, you will have to pick one which does. Unfortunately, as far as I can tell, the only way to do this is by trial and error: it seems that X-CTU will happily write firmware which doesn't run properly on the XBee. Luckily, Digi's technical support is excellent.)

To send an AT command to a remote device, it must be wrapped in a remote-AT command-frame addressed to the end device and transmitted to it via the coordinator. This is tricky! Eventually I found some Perl bindings which did the trick but before that I had some fun crafting the packets by hand, aided by a handy packet-checker. (That site also hosts a useful FAQ.)

The little script below shows how to set up the end device to read its sensors periodically and transmit them to the coordinator. This is attached to the machine on which this script runs, on a USB-Serial port. Received frames are written to the console.

Thursday, 3 November 2011

Burning an Arduino Bootloader

Being able to burn an Arduino bootloader to a new ATmega chip is useful for projects originating on Arduino and transferred to a more permanent home on a circuit-board. If their software is to be changed again, it is very handy to be able to reprogram them from the Arduino IDE.

This is primarily based on information found here and here. (The latter is an excellent resource for discovering what the various fuse bits' configuration values mean.)

Wire up the chip as described in In-System-Programming below. Then read the fuses and lock bits (in order to see what actually needs to be changed):

$ avrdude -q -q -p m168 -P/dev/ttyUSB0 -b 19200 -c avrisp -U hfuse:r:-:h -U lfuse:r:-:h -U efuse:r:-:h -U lock:r:-:h

This tells us that the chip has the following fuse-bits set (for more on the meaning of these settings, see here):
  • SPIEN serial programming and data-downloading
  • CKDIV8, SUT0, CKSEL3, CKSEL2, CKSEL0: internal oscillator at 8MHz (and other defaults)
  • The bootloader is already unlocked: 0x3f
If the bootloader is locked, it must first be unlocked:

$ avrdude -p m168 -P/dev/ttyUSB0 -b 19200 -c avrisp -U -e lock:w:0x3f:m

(Note that this also erases the chip -e.)

The main change we're going to make is to configure the chip to use an external oscillator of higher frequency than 8MHz:

$ avrdude -p m168 -P/dev/ttyUSB0 -b 19200 -c avrisp -U lfuse:w:0xff:m -U hfuse:w:0xdd:m

Next, write the bootloader:

$ avrdude -p m168 -P/dev/ttyUSB0 -b 19200 -c avrisp -U flash:w:ADABoot_168.hex

Finally lock the bootloader, to avoid it being accidentally overwritten:

$ avrdude -p m168 -P/dev/ttyUSB0 -b 19200 -c avrisp -U lock:w:0x0f:m