Thursday, 21 June 2012

Transistortester

One of the most enjoyable distractions of the past year has undoubtedly been MIT's online course in Circuits and Electronics. This sparked a renewed interest in discrete electronics which naturally led to the idea of measuring various parts' characteristics using AVRs. (The link with Arduino probably arose from a tutorial showing how to measure capacitance.)

Needless to say, once the idea had germinated it was only a matter of time before I spotted that someone else had done it, and much more thoroughly than I had ever planned to. An initial siting on Dangerous Prototypes led to the original German site where one Markus Frejek had done a magnificent job identifying and measuring characteristics of 15 different kinds of Semiconductor device (plus Resistors and Capacitors) using an AVR. His original design is downloadable here --- this package contains his circuit diagram with a neat transistor latch to turn off the voltage regulator when powering-down the AVR. (I didn't go with this in the end, preferring to use a momentary push-button to power it on.)

I built this circuit over the course of a day and I had translated the strings into English when I discovered that Markus's original announcement in early 2009 had led to a huge thread on mikrocontroller.net (which continues today!). His code had been taken up and extensively modified by Karl-Heinz Kübbeler. I went with the latest version (096k) which still works with the original circuit diagram.

The new software which is quite well packaged, is certainly the biggest AVR program I have seen. I edited the Makefile for the following settings:
#CFLAGS += -DNO_AREF_CAP
#CFLAGS += -DPULLUP_DISABLE
PROGRAMMER=avrisp
PORT=/dev/ttyUSB0 -b 19200
The file Transistortester.h should also be edited for the exact values of the resistors connected to the analog inputs, R_L_VAL and R_H_VAL --- test them with a multimeter before soldering them up. (It is probably worthwhile to use 1% tolerance parts.)  Then make && make upload && make fuses will program the microcontroller correctly.

A poor photo of my completed build on stripboard is shown below measuring an IN4148 diode. About the only change I'd make to this great project would be to introduce a software mapping layer for the connections between the AVR and the LCD data pins. (The default connections require a lot of cut-tracks and fiddly crossing-wires for the backpack arrangement I went with.)

It fits perfectly in an old perspex iPod nano case I found lying around!

Friday, 13 April 2012

Mock Pertelian


The last post concluded with a shopping list of requirements for a workable wireless display. The picture above shows a prototype of such a thing. In particular:
  • It doesn't try to be too clever: it uses an XBee as a wireless serial port and lets an ATMega do the heavy lifting, driving the display in 8-bit mode.
  • It is compatible with an existing lcdproc driver, pertelian, hence the name.
  • It bites the bullet and uses an external supply rather than batteries.
The backlight is turned on by touching a metal bolt on the top of the case. This bolt is wired to one of the ATMega's analog inputs via a solder tag. The case itself is a cheap perspex box costing about £1 from eBay.

The circuit diagram and Arduino sketch are shown below.


Update: after running for a week or so at 9600 baud, the 20x4 display was messed up. Although I never got to the bottom of it, the fault lay in the transmitting XBee: unless it was power-cycled, the problem persisted through reboots of the display and the box running LCDd. A successful workaround was to run all parts of the system at 57600 baud, i.e., both serial ports and both XBees.

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