Thursday, January 2, 2014

Getting and sending analog data over bluetooth with Arduino Pro at 8 MHz

I am thinking of using the ATmega328 running at 8MHz for the microcontroller on my wireless module.  To gather neural data, I am contemplating using an Intan chip, possibly the RHD2216 which can communicate with the ATmega328 using SPI:


I will not be able to send all 16 channels (at 16 bits) at a reasonable sample rate unless I do some compression, however, I think I can send 8 channels reasonably.  As proof of principle, I set up an Arduino Pro (ATmega328, 8MHz) getting data via SPI from an MCP3208 and sending via bluetooth.

Aside: I could compress sent data by sending only changes in ADC values, which are likely far smaller than the full 16 bits.  If I could get away with sending only 8 bits, then I could send all 16 channels at a reasonable sampling rate.

In any case, I found that on the 8MHz chip, just performing SPI communication was a little slow when using digitalWrite/digitalRead.  I started out using code from http://playground.arduino.cc/Code/MCP3208, but it ran too slow.  I had make things faster.  Here is what I had to do:

  1. Use port manipulation where possible (this make the code less portable)
  2. Remove any loops (e.g. for loops for sending bits)
  3. Use digitalWriteFast and digitalReadFast available at: https://code.google.com/p/digitalwritefast/
  4. Cycle the SPI clock with a minimal delay supported by MCP3208 - in case of 8 MHz, a single asm("nop\n") call is enough
So the result is that I can read and send 8 16 bit values from the ADC at 500 Hz.  The rate-limiting step here is reading the data, but the only way to go faster is to run faster chips.  The Intan chip is capable of running at 24MHz and has 16, 16Bit differential inputs plus amplifiers.  This may or may not be overkill for our application.

No comments:

Post a Comment