Monday, June 15, 2009

Low Rent Oscilloscope

A post found via Hackedgadget gives a description and code for an Arduino based oscilloscope. It looks pretty cool, and I must confess I certainly need an oscilloscope (a logic analyzer would be awesome, too) so I had a look. Before delving too deep here, have a look at the original post, please.

As discussed here before, the Arduino is based one of the Atmel ATmega-8 family of chips. The various ATmega-8 family members all seem to use the same analog-to-digital (A/D) conversion module, which can sample up to 10-bits of resolution, at sample rates from somewhere between DC and 75kHz, depending on resolution.

The oscilliscope code uses basic Arduino calls to read from the analog pin, and send the data out the Arduino serial port. The Arduino analog input functions don't allow you to specify a rate or resolution. You get 10-bits, and you get one sample per call. The Arduino docs say it takes about 100µS to get a sample, so about 10kHz sample rate, for a Nyquist frequency of 5kHz. So assuming you can get your data out of the chip fast enough, we have an oscilliscope with a 5kHz bandwidth. Honestly, that isn't so bad for $25 worth of parts and a few dozen lines of code.

Unforunately, there's some other problems. The code sets up the serial port at 9600 bps. RS232 serial port transmits (typically) 10 bits per byte. The code sends two bytes to get all 10 bits of data across.

9600/10 = 960 bytes per second
960/2 = 480 samples per second
480/2 = Nyquist frequency of 240Hz.

So this 'scope has a bandwidth of 240Hz. Despite this low frequency, this is still useful! If you re-coded both ends to support multiple analog pins you could use it as a logic analyzer for step-by-step debugging, etc. You can use it for measuring the kind of low-frequency stuff that's handy around the house. Like, you know, 50- or 60Hz house wiring.

But some comments in the original post say that they've bumped the serial rate up to 38400 bps, for a bandwidth of 960Hz. The comments indicate that they've had some trouble going beyond that. The A/D converter should have no trouble sampling beyond those rates, so it may be a matter of pipelining the conversions and the serial sends appropriately, or of modifying the underlying Arduino code (or writing your own handlers) to reduce the resolution, switch to interrupt-based A/D, etc.

I don't see many situations for a low-rent solution like this where one would need more than 8-bits of resolution. That would automatically double your sample rate over the serial port, and reduce the A/D settling time. Faster sampling, faster sending. With this (hopefully) simple change, we should see a bandwidth of 1.92kHz with a serial rate of 38400.

Additionally, the ATmega seems to have 64 bytes of buffer on the hardware UART. There seems to be no reason we couldn't use the A/D in interrupt mode, and have it stuff bytes in the buffer, for automatic sending. Careful balance of sample rate and serial rate would have to be managed. Oh, and the Arduino code environment doesn't directly support it...

No comments:

Post a Comment