# Increasing analog read sample rate

**URL:** <https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948>\
**Category:** Sensors\
**Created:** [February 22, 2018, 5:33pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948 "2018-02-22T17:33:58Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jaskiratubhi](https://avatars.discourse-cdn.com/v4/letter/j/a87d85/32.png) [@jaskiratubhi](https://forum.arduino.cc/u/jaskiratubhi)\
**Post date:** [February 22, 2018, 5:33pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/1 "2018-02-22T17:33:58Z")

</div>

Hi, I would like to get close to maximum analog read sample rate possible. I wrote a test code and got the sample rates around 3600 samples/s. Then I added a prescaler of 16 and got a sample rate of around 5500 samples/s. I am using a delay of 15 microseconds between each reading. The code is provided below. It just calculates time taken for reading and printing 10000 values:

```cpp
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

void setup()
{
  // set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;

  Serial.begin(250000);
  pinMode(A4, INPUT);
  int a = analogRead(A4);
  int i = 0;
  
  int start = millis();// starting the timer
  while (i < 10000) {  // reading and printing 10000 values
    a = analogRead(A4);
    Serial.println(a);
    delayMicroseconds(15);
    i++;
  }
  int finish = millis();
  int time_t = finish - start; // time taken for reading 10000 values
  Serial.println(time_t);
  Serial.println("DONE");
}
void loop()
{

}

```

I also tried a variation of above code and read it using serial communication using MATLAB and got around same sample rates.  
The Arduino code for the variation is:

```cpp
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int a;
void setup()
{
  // set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
  Serial.begin(250000);
  pinMode(A4, INPUT);
 
}
void loop()
{
a = analogRead(A4);
    Serial.println(a);
    delayMicroseconds(15);
}

```

Please let me know if there is a way to increase the sample rate more than this.  
Thanks!

---

<div class="post-metadata">

**Author:** ![TonyWilk](https://avatars.discourse-cdn.com/v4/letter/t/f07891/32.png) [@TonyWilk](https://forum.arduino.cc/u/TonyWilk)\
**Post date:** [February 22, 2018, 6:22pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/2 "2018-02-22T18:22:35Z")

</div>

> jaskiratubhi:  
> Hi, I would like to get close to maximum analog read sample rate possible.

> ATmega\_328\_datasheet:  
> By default, the successive approximation circuitry requires an input clock frequency between 50kHz and  
> 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency  
> to the ADC can be higher than 200kHz to get a higher sample rate.  
> ...  
> A normal conversion takes 13 ADC clock cycles

So, at 200kHz, the best will be around 65uS/convert ~ 15,000/sec

Remove the delayMicroseconds()

The _Serial.println(a)_ at 250000 baud will take approx. 40uS/char, 4 characters = 160uS  
I think it will slow to this rate once the serial output buffer is full (i.e. about 6,000/sec)

Yours,  
TonyWilk

---

<div class="post-metadata">

**Author:** ![wvmarle](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/wvmarle/32/1013044_2.png) [@wvmarle](https://forum.arduino.cc/u/wvmarle)\
**Post date:** [February 23, 2018, 11:45am UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/3 "2018-02-23T11:45:56Z")

</div>

The clock frequency should be 50-200 kHz for full 8-bit resolution. On a 16 MHz system and /128 prescaler you'd have a frequency of 125 kHz, so 9615 samples per second.

You can increase this rate - the ADC is rated up to 1 MHz so a /16 prescaler - but you lose resolution: the effective resolution is just 8 bits at that rate. But you can get almost 77,000 sps.

---

<div class="post-metadata">

**Author:** ![robtillaart](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/robtillaart/32/1098811_2.png) [@robtillaart](https://forum.arduino.cc/u/robtillaart)\
**Post date:** [February 23, 2018, 12:54pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/4 "2018-02-23T12:54:53Z")

</div>

instead of the blocking analogRead() you can do it async way

See my experimental code here - [Experiment - split up analog read in 3 steps - Libraries - Arduino Forum](http://forum.arduino.cc/index.php?topic=109259.0)

(still need to make a wrapper class for that ... )

---

<div class="post-metadata">

**Author:** ![wvmarle](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/wvmarle/32/1013044_2.png) [@wvmarle](https://forum.arduino.cc/u/wvmarle)\
**Post date:** [February 23, 2018, 1:07pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/5 "2018-02-23T13:07:16Z")

</div>

IIRC there's an interrupt available for the ADC, that's triggered when ready. May be useful in the "free running" mode: have it trigger an interrupt every time the reading is done, have the ISR read the registers (only the high byte or also the low byte if you're sampling at \<200 kHz), and deal with the data in your code.

---

<div class="post-metadata">

**Author:** ![TonyWilk](https://avatars.discourse-cdn.com/v4/letter/t/f07891/32.png) [@TonyWilk](https://forum.arduino.cc/u/TonyWilk)\
**Post date:** [February 23, 2018, 5:44pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/6 "2018-02-23T17:44:57Z")

</div>

> wvmarle:  
> You can increase this rate - the ADC is rated up to 1 MHz so a /16 prescaler - but you lose resolution: the effective resolution is just 8 bits at that rate. But you can get almost 77,000 sps.

Yes, but that would be a sample every 15uS or so, to output that over async serial as text you would need a baudrate of over 2Mbps

**jaskiratubhi** has _Serial.println(a)_ in the timing loop

Yours,  
TonyWilk

---

<div class="post-metadata">

**Author:** ![wvmarle](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/wvmarle/32/1013044_2.png) [@wvmarle](https://forum.arduino.cc/u/wvmarle)\
**Post date:** [February 23, 2018, 5:57pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/7 "2018-02-23T17:57:45Z")

</div>

That's another problem indeed. Getting the data out. I2C or SPI would work a lot better.

---

<div class="post-metadata">

**Author:** ![robtillaart](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/robtillaart/32/1098811_2.png) [@robtillaart](https://forum.arduino.cc/u/robtillaart)\
**Post date:** [February 23, 2018, 6:40pm UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/8 "2018-02-23T18:40:24Z")

</div>

you could also use a teensy 3.5 which is much faster ...

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 6, 2021, 10:20am UTC](https://forum.arduino.cc/t/increasing-analog-read-sample-rate/509948/9 "2021-05-06T10:20:35Z")

</div>


