Monday, October 6, 2008

The AVR Butterfly as a Data Logger

I was browsing some messages in the Arduino forum today and I ran across
this great Butterfly data logger project.

It gives some neat examples of using the $25 Butterfly board (for $45 you can get it on a PCB breadboard with all the goodies already attached, great deal).

I'm using the butterfly as the basis for developing my Itron meter reader. I'll do the development on the butterfly, then transfer the program to one of the 2313 boards I developed a few years ago:



It's pretty chunky, but it's got the power supply and serial port and a place to put the RF board, it should be perfect. It's also got some space that I could stick some I2C flash memory onto for data logging. The 2313 is a pretty limited device, it won't be able to log data for very long with out some off-chip memory.

I've mounted the butterfly onto the back of a 2 D cell battery and affixed it with a bit of ShapeLock. I soldered on some headers to let me connect to the ports and made a serial cable from an old mouse cord (also using ShapeLock).



It looks a bit crappy, but it doesn't fall apart, and the other board looks nice. :)

Next step is to write a program that will read the output of the RF board and send it to the computer via the serial port. Once I get a look at the waveform I can make some decisions about how to decode it on the AVR.

Update 2008-Dec-3

I've spent quite a few hours over the past few weeks working with the Butterfly and AVR Studio to try to get it to do what I want. Since this is the first time I've worked with Mega processors it has been a bit of a learning process. I spent a couple of weeks working on the software and finally got really stuck, so I took a break for a week and came back to it last night. Almost immediately I corrected the problems and now have it reading the output of the RF board from a wireless temperature monitor (there's another post around here somewhere about that monitor).

I am using what I suspect is a pretty inefficient method to read the data stream, but it's working. I've configured the Butterfly's Mega169 Timer1 to trigger an interrupt every 100uS which updates a system timer counter. The pin change interrupt is set up to watch for changes on the joystick pins and to set a variable to idenfity which button changed and whether it is up or down. This information is made availble through a 'keypressed' funtion. In the main loop I read the keypressed function until I get a valid input, then I read the timer value and the button state (up or down) , reset the timer, then write the string-formatted timer value and button position out to the serial port (which runs at 115200).

This is all built on the GCC port of the Butterfly source code with some minor adjustments and additions from the AVRFreaks board (a new, faster and more flexible OSCCAL_Calibrate function, for example). In order to make it easier to learn what I'm doing I tried to stick with the basic archetecture of the Butterfly code. That's got it working, but the way I'm using the timer is really pretty dumb. It's easy to understand though, and it works, so for the time being I'm going to leave it. If I do move this down to the 2313 I'll have to be much smarter about resource usage, I don't think the 2313 at 4Mhz would handle this very well.

The datastream going to the computer is currently being read by a simple C# app that uses ZedGraph to display the live data stream. It normalizes the bit widths for display and seems to do a pretty reasonable job of making the data visible. Next I need to set it up to log the data so I can save to a file for analysis.

If I was going to continue with the temperature monitors I'd spend some time analysing the bitstream and compairing it to the transmitted temperature. From what I've seen it transmits the data packet four times and each transmission consists of about 16 bits (maybe 20, I'm not sure if the last four are data bits or framing). The temperture range is something like -22°F to 122°F, or -29°C to 50°C, a range of about 79°C or 142°F. It includes a tenth degree figure as well, but I'm not sure if that digit has a resolution of 0.1 or 0.2.

Regardless, the project is not to read the temperature data (although that would be interesting too), but to read the datastream from the Itron meter. Fortunately the datastream format for that is documented, so there won't be any time-consuming reverse-engineering there.

At this point the next step is to get the 800Mhz RF receiver set up to see if I can read the data coming from the meter. I'll have to rig up something to connect to the header pins on it, they're closer than 0.1" spacing of common headers and I don't have anything that connects to them.

Here's a picture of the bitstream from the temp monitor. Each of the '1's are 0.5mS.