Faster Analog Reads on Arduino

I work on an open source high speed photography trigger project called the Camera Axe (http://www.cameraaxe.com). Every week I make a video about various technical photography related topics. This week I modified the Camera Axe code to do faster analog reads. I figured this might be useful to other Arduino users out there. See the video at: http://www.techphotoblog.com/tpb-24/

  // Setup faster analog reads
  // ADPS2  ADPS1  ADPS0  Div Factor
  // 0      0      0      2
  // 0      0      1      2
  // 0      1      0      4
  // 0      1      1      8
  // 1      0      0      16
  // 1      0      1      32
  // 1      1      0      64
  // 1      1      1      128
  // Default set by wiring is 128 (16 MHz/128 = 125 Khz)
  // Since a converstion takes 13 clocks the sample rate is 125Khz/13 = 9600 Hz or about 100 us.
  // By setting the div factor to 16 analog reads will be 8 times faster.
  ADCSRA |=  (1<<ADPS2);
  ADCSRA &= ~(1<<ADPS1);
  ADCSRA &= ~(1<<ADPS0);

Do you see any difference in accuracy of the result at the different speeds?

That would be my question also. As there has to be a tradeoff involved as faster has to have an effect on sample and hold when channel selection changes are made to read different analog input pins, rather then just reading the same pin. Source driving impedenace is already an issue with using the analog input pins and I wonder if speeding up the ADC would have a even worst problem with driving impedeance?

I suggest the some extensive testing should be done to see what is gained and given up with this method, as I'm sure there is a 'hidden' tradeoff here.

Lefty

I completely agree that there is a trade off (this was mentioned in the video). I tried a few different voltages and seemed to give the same results. That said I was doing some filtering of the results (average of 5 reads). So for my use this is complete acceptable, but I agree for general use some data on the amount of variance would be useful.

That said I was doing some filtering of the results (average of 5 reads)

like this?

sum = 0;
for (int i=0; i< 5; i++) sum += fastAnalogRead();
val = sum/5;

better average 4 readings, the division will be a shift 2

sum = 0;
for (int i=0; i< 4; i++) sum += fastAnalogRead();
val = sum >> 2;

quite faster than division by 5 :wink:

Or did you do something like this? (sort of running average)

val = 0;
for (int i=0; i< 5; i++) val = (val + fastAnalogRead()) /2;

I've been sampling audio at 32khz using UNO. It sounds and appears visually to be accurate with different sine waves. If I take a simple average of every 4 samples I do not need a Nyquist filter in hardware.

Do you need the faster analog reads so the call to analogRead does not block as long (Arduino has other / "higher priority" work to do)?

Or do you need faster analog reads so the Arduino can respond faster to a change?