Delay between multiple analogReads I'm trying to read 4 analog inputs (1kHz speed). I changed the prescaler to 16 for my Arduino Leonardo according to this link. I then tried to read the analog pins and I used the following code to display the time and the readings:



#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &amp;= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
double t = 0;
void setup() {
  int start;
  int i;
  #if FASTADC
  // set prescale to 16
  sbi(ADCSRA, ADPS2);
  cbi(ADCSRA, ADPS1);
  cbi(ADCSRA, ADPS0);
  #endif

  Serial.begin(9600);
  Serial.print("ADCTEST: ");
  start = millis();
  for (i = 0 ; i &lt; 1000 ; i++)
    analogRead(0);
  Serial.print(millis() - start);
  Serial.println(" msec (1000 calls)");
}

// the loop routine runs over and over again forever:
void loop() {
  // print out the value you read:
  t = millis() / 1000;
  Serial.print(t);
  Serial.print('\t');
  Serial.print(analogRead(A0)); delay(1);
  Serial.print('\t');
  Serial.print(analogRead(A1)); delay(1);
  Serial.print('\t');
  Serial.print(analogRead(A2)); delay(1);
  Serial.print('\t');
  Serial.println(analogRead(A3)); delay(1);
}


I connected 2V from the DC supply to all the 4 channels and the readings were similar. I used the output from the serial monitor and pasted the readings for 1 sec in Excel to see the frequency. With a 9600 baud rate and no delay between the readings I got 200 Hz (for the 4 analog inputs).

Why is that happening? And is there a relationship between the sampling frequency and the baud rate? Is my way of finding the frequency correct? If not what's the right way?

Finally, I'll be plotting the readings in Matlab, so I guess this will affect the sampling frequency. How can I control it so that I'm sampling with 1kHz rate for all the channels?

Here is the screenshot of the readings from the 4 channels (2V input).



Summarizing everything, I need to know the following:


The effect of adding a delay between every two readings on the accuracy of the readings and the sampling frequency.
How to find the best sampling frequency for every input and how to control it?
Will using Matlab to plot the data affect the sampling frequency?


Thanks.

EDIT: I accepted the answer below, if anyone has the same problem , please make sure that you change the prescaler as I mentioned above for the best results.
At first I thought that the main problem was not that you too slow at sampling, but that you were too slow at transmitting the data. As Edgar already stated, at 9600 b/s you need 22.88ms to send a line, so the maximum frequency is less than 50Hz.

However as you experienced, the speed you are getting is 200Hz. This is because that calculation is right in the case of a real serial interface. Arduino Leonardo, on the other hand, emulates the serial interface. But.. There is no such thing as baud rate. If you look at the CDC emulation source code you will see that the baud rate you pass to the begin function is ignored.

So... Why is it still slow? Because you are using the delay function! You are waiting for 1ms every time you perform an acquisition, and then you still have to perform all the sending. This has two errors embedded: 1) using the delay function breaks the timing - better use a timer - and 2) you are too slow.

Now, if you want a 1kHz sampling (or any delay multiple of 1ms) you already have a timer running (so you can just use that):

#define INTERVAL_LENGTH_US 1000UL

unsigned long previousMicros;

void loop()
{
    unsigned long currentMicros = micros();

    if ((currentMicros - previousMicros) &gt;= INTERVAL_LENGTH_US)
    {
        previousMicros += INTERVAL_LENGTH_US;

        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);

        Serial.print(((double)currentMicros) / 1000000UL, 1); // 1 is the number of decimals to print
        Serial.print('\t');
        Serial.print(val_a0);
        Serial.print('\t');
        Serial.print(val_a1);

        Serial.print('\t');
        Serial.print(val_a2);
        Serial.print('\t');
        Serial.println(val_a3);
    }
}


NOTE: The millis() function is replaced by micros() according to Edgar's and Nick's comments.

Change just the define to change the sample time. Now its set to 1000us (i.e. 1ms, so 1kHz), but don't go much higher otherwise you will have to check accurately the sampling time and the transfer speed. The t variable is not needed anymore.

Just a side note: this will also fix the bug in your code that prevents the program to display the current timing (instead of printing 2.5 it prints 2.0).

If you need a faster sample rate you should use another timer to get the correct timing, but again avoid delays. Not needed anymore