RS-232 ADC Sampling Interface

Sometimes you just want to sample a DC voltage periodically and log the results on your PC. The Atmel ATtiny13 has a four-channel multiplexed 10-bit ADC capable of sampling at up to about 15 kHz. Its small package, low cost, and modest program memory seem to make it ideal for a quick 0-5 Volt sampler feeding a PC. However, the ATtiny13 doesn't have a USART, so getting the data out of the device requires a little bit more effort than with other AVRs.

The Atmel ATtiny13V ADC Sampler to RS-232 Interface


To get around this lack of dedicated serial IO hardware I simply implemented serial TX in software. The tiny13 counter is set-up to interrupt the processor at the baud rate, a simple state machine bashes out the serial signal on a digital IO pin when there is data to send. The CPU spends most of its time asleep either in idle or ADC noise reduction mode.

Unfortunately the lack of an additional hardware counter means timing the ADC sampling is not very easy. As the application is simply "sample at a reasonable rate" (quazi-DC logging use) rather than a precise rate this is of no consequence, but perhaps with more work on the software it would be possible to specify the sample rate. The sample rate is deterministic, but as I am using the internal 9.6 MHz oscillator the rate isn't completely stable (an external clock could be used if so desired, at the cost of an input channel). There is also a phase-shift between the channel samples: ADC conversions are executed in series (because there is only one ADC in the chip). After all conversions are complete the results are converted into decimal text and sent down the serial line. Once the data has been sent sampling begins again. The full 10 bits of ADC data are delivered, the software in the PC can truncate the data if that level of resolution is not required. The text format is simply a line of four decimal numbers, the first is a monotonically increasing number (the number of ADC conversions executed since reset), the following three numbers are the ADC data 0-1023, finally a CR LF pair terminates the line (canonical text):

32745 445 440 413 32748 448 442 422 32751 453 446 434 32754 460 456 448 32757 465 461 458 32760 468 465 464 32763 470 470 467

The fourth ADC multiplexer channel in the tiny13 requires the reset line to be dedicated as an IO pin. Setting this fuse breaks simple serial programming, so I chose to use only three of the available four channels. You can alter the code if you don't mind HV programming, or if you want to sample less channels (faster). The baud rate could be increased, but eventually the jitter of the internal oscillator will start causing problems. 9600 is fast-enough for my current uses.


For RS-232 signal level conversion I use the trusty old MAX232 (as I happened to have some in the junkbox). More recent chips require less external capacitors, or even none at all. Analogue input protection is quite primitive, just a 1k series resistor. It is expected the sensor amplifier and conditioning circuit will guarantee 0-5 volts. As this is just for my experimentation, I can live with that.

Prototype Lash-up with MAX232

I love my wiring pencil, but I think I've said that before!

Back-side of the Completed Sampler Interface


I had a lot of trouble with the software TX. My code was fine, but after much frustration I found the sink-driver of the PB0 pin in the particular tiny13 I was using was dead! When I added a LED to see what was going on it incidentally implemented a pull-down and things starting working fine. Switching over to PB1 cured the problems, but ideally I should replace the chip with one I haven't accidentally cooked in previous experiments.

There might be enough space left to implement software RX and have commanded sampling, rate and channel setting, etc. A larger device could easily do this, the current code is about 800 bytes. The full state machine for a software USART might not leave a lot remaining for the application in the tiny13; parsing textual commands is probably out.

Linux makes it really easy to use the device. After issuing stty against the appropriate /dev/ttySx device to configure the port you can simply cat data from the device node into a file. I doubt I'll write a client-side utility, as this interface is fine for my purposes and can be scripted up as needed. The data format interfaces well with GNUplot (somewhat by design), and is trivial to manipulate with awk or other languages. I used canonical text (CRLF) for "Microsoft compatibility" but the CR is easily removed with the appropriate stty option (igncr) while using from Linux.



title type size
The ATtiny13 C-code For RS-232 Linked ADC Read-out application/gzip 5.326 kbytes