peteg's blog - hacking - avr

Further steps with the talking clock.

/hacking/avr | Link

I bought a couple of the MMA7660 accelerometers I mentioned some time ago from Farnell (before their gender op). The chips are incredibly tiny, 3mm to a side, and 0.5mm pitch legless contacts have to be seen to be believed. Soldering wires onto those was beyond me, and I was fortunate to have Aaron at NICTA kindly solder one to a board for me. Etienne more-or-less inhaled the other one. Some basic prodding seemed to indicate that the device was still functional after this surgery.

Much later I tried to solder some wires to the board, using NICTA's excellent facilities (Dremel, high-end electric iron and stereoscopic magnifier). Suffice it to say that the device showed no signs of life after that. Fortunately the market has responded to my demand in the intervening period: the Mad Scientist Hut sold me a couple of these devices pre-attached to macro breakout boards. Their prices are OK but their shipping is very expensive, at about $10 for the pair. I guess it would make sense if I'd bought fifty of them, but I didn't.

Suffice it to say that the bidirectional circuit mentioned in SparkFun's tutorial did the trick of interfacing the circa 3v TWI/I²C levels of the accelerometer to the circa 5v used by the AVR and the rest of the circuit. I fabbed it on some stripboard and get plausible readings from the sensor.

The penultimate bit of hardware hacking was to switch off the speech chip when quiescent, with the goal of getting the current draw under a milliamp in the most-of-the-time case. Doing this with is a FET is entirely straightforward, but the current draw remains a ridiculous 6.5mA. I think (hope) that is fixable in software. Adding the batteries — a button cell as a backup for the RTC, and four NiMH AAs — is largely a mechanical problem. Later I might also try to bring the volume under software control.

I have begun trying to flesh out the control software for this thing. I'm trying to avoid writing spaghetti C and have been a little successful, but am hoping for a more abstract way of writing the core state machine as it will involve commands coming as data on the U(S)ART and timeouts, as well as the presumably complicated interactions the accelerometer will allow. Maybe I can get by with less overkill than Esterel.

The code is at github. Possibly of interest to others is the growing MMA7660 driver for AVR.

AVRUSB serial connections going for $AU3 a pop.

/hacking/avr | Link

As I said a while ago:

[T]his bloke has a super-cheap approach to USB interfacing, viz using those USB-RS232 cables that don't do level conversion. I'm off to buy a cache of them from eBay.

Well, I bought five of those cables from these guys in China for a grand total of about $AU11. They turned up less than a week later, and are about as cheap and nasty as their price suggests.

The first thing to do was to ensure the Mac recognised them. This was painless as they look like a Prolific PL2303, about as stock as they come. The second step was to extract the circuit board from the (very cheap and very nasty) serial plug. This took a while as the plastic is pretty tough; next time I'll heat it up a bit first, or perhaps try out the Portasol's hot knife. Also I smashed the ceramic resonator in the process, which was a mixed blessing as apparently they are not very stable wrt temperature, so replacing it with a 12MHz crystal is probably worthwhile anyway. Good thing I got something like a lifetime supply from Sure a while ago.

The remaining problem is that RS-232 inverts the signals: low is a logic 1. These cheap cables treat low as something like 0v, so there's nothing fancy required to get the signal the right way up; two instances of the circuit at the bottom of this page did the trick, one for each direction. I tried a 10kΩ / 100kΩ pair as he suggests but the power sucking 1kΩ / 10kΩ combination seemed necessary.

After wiring that up, the magic incantation screen /dev/tty.PL2303-0000xxx 9600 for some xxxx worked fine as a zero-functionality terminal. It seems that 9600 baud is the limit with the default 8MHz-divided-by-8 clock of the ATmega328P, which surprised me as I wasn't expecting anything more than about 1200 baud to work due to the probably huge error in the clock.

So all up there's the cable ($AU2.20), two transistors (Jaycar is expensive here, $AU0.26 per BC549, where Farnell only wants $AU0.10 or so), four resistors (marginal) and some time. Much better than $US20 for a "USB TTL cable".

The other thing to note is that while the AVR's UART is incredibly easy to get going, the code depends a lot on which particular chip you've got: I had to pepper the I/O register names in mine with 0s for no reason I could fathom, for the ATmega328P only has one U(S)ART. (Yes, yes, there are a few other serial interfaces but those are hardly universal; they are not even asynchronous AFAIK.) Here's the guts of it:

#include <stdint.h>

#include <avr/io.h>

#define BAUD 9600

static inline void
UART_read(uint8_t *c)
{
  while(! (UCSR0A & _BV(RXC0)))
      ;
  *c = UDR0;
}

static inline void
UART_write(uint8_t c)
{
  while(! (UCSR0A & _BV(UDRE0)))
      ;
  UDR0 = c;
}

static inline void
UART_init(void)
{
#include <util/setbaud.h>

  /* Set the baud rate */
  UBRR0H = UBRRH_VALUE;
  UBRR0L = UBRRL_VALUE;

  /* Turn on the transmission and reception circuitry: 8 N 1. */
  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);

#if USE_2X
  UCSR0A |= (1 << U2X0);
#else
  UCSR0A &= ~(1 << U2X0);
#endif
}

Next up is fabbing it on some veroboard.

A talking clock.

/hacking/avr | Link

Hacking AVRs is too easy these days: without any real snags I got an LED flashing on one of the pins of an ATmega328P. From there it was a short step to hooking up an SPO256-AL2 General Instrument speech synthesis chip from circa 1980 and getting it to talk. Making the AVR listen to the SPO256-AL2 required me to read the AVR manual: the AVR's GPIO pins have distinct registers for reading inputs (PINx) and setting outputs (PORTx), unlike the ARM in the ts7250.

I bought the SPO256-AL2 at a good price from a bloke in Melbourne. Email me if you want his details.

Slightly harder was getting the AVR to talk to the DS1307 real-time clock hanging off the TWI/I²C bus. As it didn't just work, I put off debugging this until I could borrow an oscilloscope from Andrew T. He lent me a venerable BWD 539D that was probably abused to within an inch of its life in the electrical engineering laboratories back when I was an undergrad. Suffice it to say that even with my inexpert knowledge it quickly showed the TWI/I²C bus was alive, and with some minor software fixups things came good.

On that front I started with something not too far from Peter Fleury's venerable TWI/I²C code, and ended up with something a bit cleaner and more abstract. There really isn't much going on with that protocol.

Today I wired up a DS18B20 one-wire temperature sensor in parasitic-power mode. It worked immediately using this driver after some minimal configuration and plumbing. Too easy.

My next step is to add an accelerometer, specifically this cheap one from Farnell. I think it is pretty crap as far as accelerometers go, being intended more for the user-interface sort of application I need it for: tap, double-tap, I'm-this-way-up, don't-shake-me-so-hard. Soldering it will be fun, and I need to figure out how to do the level conversion between the 5v required by the SPO256-AL2 and the DS1307 and the 2.8v this accelerometer wants on the TWI/I²C bus. SparkFun's tutorial makes it look not impossible.

After that I hope to put all this stuff on a PCB and polish the software. The power consumption is a bit crazy, with the SPO256-AL2 chewing about 75mA at 5v, as one would expect from vintage TTL technology. It could probably be simulated by a low-end AVR for a milliamp or less now.

Here's a sample of it saying the time and the temperature. The code is at github.

On another note, this bloke has a super-cheap approach to USB interfacing, viz using those USB-RS232 cables that don't do level conversion. I'm off to buy a cache of them from eBay. Possibly cheaper is the mostly software approach.

AVR programmer and demo board from Sure Electronics.

/hacking/avr | Link

For many reasons, mostly not so good, I want to get the gear needed to hack some kind of microcontroller. After working on Andrew T's microphone board, and assembling the Bulbdial kit, I'm pretty sure AVRs are the devices to use, though I expect others will swear by PICs. In both cases there are way too many to choose from.

I plumped for an implausibly cheap programmer and USB / LCD / atmega16 demo board from Sure Electronics, hoping they would be happy with each other. Sure has an eBay shopfront, but it is cheaper to order from them direct. They screwed up my order a bit, giving me an LED controller or something in place of a power supply. I decided to wear that, as the postage was cheap and delivery rapid — Hong Kong Post airmail in about a week [*].

Things look promising. The board has a lot of stuff on it — a USB port, a temperature sensor, the LCD panel, and most importantly, all the ports broken out. Unfortunately it uses a Silicon Laboratories CP2012 chip to talk USB, and their driver for Mac OS X is pretty terrible, inducing kernel panics at critical moments, like device disconnection. Apparently there is a Linux driver now. The Windows driver is fine.

The programmer and board aren't totally happy with each other though; my first attempts at scraping programming info from the board failed, with the sort of errors that made me think the programmer was fine but the board recalcitrant. Fortunately one of the wise heads at AVRfreaks told me to remove the LCD board, and sure enough magic happened.

The plan is to prototype things on this board and then construct final versions on veroboard; the hope is that the other AVR chips are close enough to this stock atmega16 to reduce porting to a formality.

[*] Upon closer inspection I found that they got my order spot-on. The power supply is half of some kind of LED driver board, the other half being some kind of PIC, and hence the board is a lot larger than I expected. It has a different part number to what I ordered.