Filed under: Charge Controller. Tagged as: data logger, high speed data logger, leaf labs, leaf labs maple, maple, open source, open source data logger.
Among it’s many features, the Maple sports a 32-bit ARM microcontroller, is Arduino compatible in terms of both hardware and software, and uses open source, royalty free development tools. Like the Arduino, it programs via a USB port and all the development software installed and ran flawlessly on my Aspire netbook runing an Intel Atom N450 processor. My experience playing with this neat little device has been suberb. Everything installed and ran flawlessly.
The Wiring language used to program the board was very quick to pick up. The language is just a light wrapper that assists people to get strait to coding without having to worry about all the device specific operations that strait C coding requires.
Creating a Data Logger Hardware
I needed to run a test at work that required a high speed data logger. Since we didn’t have the budget to purchase one, I decided I’d give a shot at quickly building one out of a Maple and this SD Card Shield from Seeed Studios. Although it was origonally developed for the Arduino, it plugs right onto the Maple (I’m using Rev 5, by the way) since it’s pin compatible.
Voilà! I now have a high speed data logger! All I need now is some software to make it work.
Create the Data Logger Software
Creating the software wasn’t as easy as putting the hardware together, but it was still pretty easy. Thanks to Leaf Labs awesome forum and the extensive documentation, it was largely an excersize in downloading open source code and making everything play ‘nice’. I’ll go through each stage of the development for the sake of posterity.
Implementing a Fixed Point Math Library
For me, an attractive feature of using the Maple is that it uses a 32-bit processor. This means that I can use native 32-bit integers and implement a fixed point math library to implement math-heavy algorithms such as digital signal processing (DSP). It’s not as accurate using a floating-point processor, but it’s orders of magnitude better than trying to use an 8-bit processor. So for me, the first order of business was implementing a floating point math library.
I wasn’t the only one to lock onto this major feature of the Maple. This Fixed Point Math Library thread in the forum pointed me at the libfixmath library as well as forum user Crenn‘s benchmarking code.
The trick to getting the library working was to drop the libfixmath folder into the libraries folder of the Maple IDE installation directory.
Combining the fix16 Math Library with the Analog to Digital Converter (ADC)
Next, I needed to read a value from the ADC and convert it to a voltage using the fix16 math library. This ADC_test.pdf program I wrote did just that. Next, I needed to be able to write these values to the SD card in order to create a full data logger.
Writing ADC Data to the SD Card
In order to write data to the SD card, I needed a source code to enable the Maple to talk with the SD card on the shield. Going back to the forum, I found this thread which pointed me to the SDFat Library for the Maple.
Again, implementing the library into the IDE required dropping the mapleSDfat folder into the libraries of the Maple IDE installation directory and rebooting the IDE. A couple hours of tweaking and I was able to produce this ADC_SD_Write.pde program, which now lets me read an ADC value, convert it to a voltage, and write that value to the SD card once per second.
Speeding Up the Data Logger
At this point I was really close! For the test I wanted to run, I needed to sample 3 channels as fast possible. Since I’ve developed data-logger like for other hardware platforms, I know from experience that the fastest way to operate is to create two FIFO buffers in memory. I can then implement an interrupt handler that is called at a set amount of time to read the ADC and drop the data into the FIFO. Once the first FIFO fills up, I point the interrupt handler at the other FIFO while I write the first FIFO to the SD card in the loop() part of the program.
Ideally, I’d like to sample each channel at rate of 1000 samples per second (1 ksps). That means I need to create an interrupt vector that is services 1000 times per second, or 1 millisecond. This Timer_Interrupt_test.pde program does just that.
Putting It All Together
After much fiddling, I wasn’t able to achieve a rate of 1 ksps with 3 ADC channels. The best I could do was 300 samples per second. Still, that’s really fast and lets me sample signals up to 150 Hz (see Nyquist sampling theorem). The data logging code is available in this program: Data_Logger.pde
I could speed up my sample rate significantly if I could write data to the SD card faster. The current program stores data as ASCII text in a CSV file. If I store data on the SD card as binary data, I could easily achieve a sampling rate of 1 ksps for 3 channels. That will be my future work.
As I said at the beginning, I’m doing all my development on an Aspire One netbook with an N450 processor. Just like the one below. It’s got an awesome battery life and lets me program for hours, wherever I happen to be at – home, the coffee shop, or my boat.