Friday, 17 February 2012

Heroic Failures #1

This is the first in a (hopefully short) series of posts describing things which seemed possible beforehand but which turned out unsatisfactorily. It is inspired by a quote from Fred Brooks (via Nat) "Good judgement is the result of experience ... Experience is the result of bad judgement."

The initial motivation was dissatisfaction with the fact that all current (to my knowledge) lcdproc displays must be tethered to their host by either USB or Serial and that they might be much more useful if they could be positioned where they were needed.  When this was coupled to the observation that XBees are pretty smart and have lots of I/O, it seemed that driving a 4-line LCD display directly from an XBee using a couple of AA batteries might be a runner. The circuit is shown below and shows the display being driven in 4-bit mode with a couple of extra lines for EN and RS (I could only find a Series-1 Eagle part and used a Series-2 XBee so some of the pin names are a bit off).


One hacked lcdproc driver and some low-level XBee and LCD C-programming later, it worked... but only just!
  • The display wouldn't work properly with 3.3v: it required 5v and hence another regulator for the XBee, e.g., an Explorer Regulated breakout board,
  • It also wouldn't work (for very long anyway) on batteries: when its backlight was on, the display drew 150mA,
  • Maintaining an out-of-tree driver (for lcdproc) is painful,
  • It is extremely slow (about 1 char/sec). This is because each bit is framed in an XBee packet (thus requiring ~100 bytes to get one character to the display).

Monday, 30 January 2012

Twilight Mk2


The picture shows an updated version of Twilight driving a 3W LED inside a salt crystal. The new circuit:
  • does away with the LEDs, using the controlled light itself as an indicator,
  • ditches the variable resistor, using a long-press on the switch to indicate the light-level at which to switch on,
  • stores this light-level in EEPROM to preserve it across power cycles
  • uses an ATtiny85 for a smaller footprint
When switched on for the first time, the light is flashed quickly four times. When the environment reaches the desired level of twilight, the user presses the switch for two seconds to indicate this light level is to be stored. The light is then flashed slowly twice.

A circuit diagram and sketch (for Arduino 1.0) are shown below.


Wednesday, 14 December 2011

Homebrew ISP Shield

Mocking up an ISP on a breadboard as described below is handy as a once-off but gets old very quickly. The pictures show a little "shield" for the homebrew Arduino, which costs about a euro for parts and a couple of hours of time.

Although this shield takes a little longer to construct than it does to wire up the breadboard, it also boasts status LEDs, for Heartbeat, Error and Programming, which ArduinoISP can drive but which were always too much trouble to wire up. (The Heartbeat LED is particularly pretty.)

Soldering it together doesn't take too much effort. The main thing to remember is to solder the headers first on a flat surface so that they are quite vertical and protrude the same distance below the board. (This is actually the trickiest part of the job.)

Since they're so cheap, there's no point not to make separate shields for the 8-pin and 14-pin Tiny AVRs. We'll do these as needed.

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 digi.com). 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
0xdf
0x62
0x1
0x3f

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

Friday, 30 September 2011

Remote Sensing with XBees, Hardware

The schematic below shows a battery-powered wireless remote temperature and humidity sensor. The wireless part is provided by an XBee Pro Series 2, the humidity sensor is an HIH-4030 and the temperature sensor is an LM335a.


The XBee is configured as an 'end-device' and periodically transmits three analog samples to its 'coordinator': humidity on AD0, temperature on AD1 and supply voltage on AD2.

The most important design decision was to run the XBee standalone, without the aid of a microcontroller, which had several consequences for the resulting circuit:
  1. It constrained the choice of humidity sensor to the relatively-expensive Honeywell part, which outputs a voltage proportional to temperature. (Cheaper parts, such as this one, output digital data requiring a microcontroller to present it to the XBee.) 
  2. The Honeywell part demands a 5v supply, and the XBee no more than 3.3v, entailing the further purchase of an Explorer Regulated to step-down the supply voltage for the XBee. (This is not shown in the diagram.)
  3. The analog inputs on the XBee can only read up to 1.2v, so each sensor's output must be passed through a resistive divider to scale it down.
  4. To conserve power, the XBee spends most of its time asleep, waking only to read the sensors. Its ON/SLEEP pin is asserted when it wakes but, of course, doesn't supply the correct voltage for the sensors, so a transistor is needed to switch the 5v supply.
Had the decision to use a microcontroller been taken instead (using an ATtiny85v, say) the entire circuit could have run from 3v, considerably reducing cost and hardware-complexity.

(The diagram was made with Eagle for which Sparkfun provides a library of circuit elements for most of the parts it supplies.)

The software side of this project will be described in a subsequent posting.

Saturday, 10 September 2011

Open Source is Wonderful, part 94

A couple of years ago, I bought an ICE Tube clock kit from Adafruit Industries. Not having touched a soldering iron in twenty years meant that I found this quite a tricky build, wiring the tube in particular. (However the online instructions were excellent, and can only have improved since.)


At the time, I'd spotted that at its heart was a programmable chip of some sort but having no idea what an ATMega was: I was happy enough to have built the thing and bask in the reflected admiration of visitors.

Until last night, that is, when I noticed that it was out by five minutes, having only been adjusted six months earlier! Comparing this with my ancient (though also digital) radio alarm-clock whose time is only adjusted after a power-cut, I wondered if I didn't know enough about AVRs now to modify the firmware to implement some sort of drift adjustment.

So I googled "icetube firmware" to find the software it had come with, and discovered there are at least four different firmware versions available, two of which have a drift adjustment feature. I went with jsgf's one, which has a bunch of other cool features, such as day- and night- brightnesses, animated transitions and the ability to turn off the seconds' display altogether (this was a deal-breaker for me originally to use it as an alarm clock).

So I ripped out the chip, discovered it was an ATMega 168v, and threw together a programmer for it, based on the In-System Programming article below --- I've updated the table there with pins for the ATMega series. Total time to implement this feature thanks to OSS? 30 minutes, as determined by the amount I had to update the clock by when I powered it back on!