I am reading analog sensor data using Arduino nano, and the required sampling rate is around 1kHz. I am using the AnalogReadSerial example provided by Arduino with a delay of 1ms, so I am expecting to get around 1000 samples per second or slightly less due to the ADC conversion delay. However, the maximum number of samples I am able to get in my laptop a little bit less than 200 samples per seconds. I have tried increasing the baud rate to 115200 but that was not helpful. Am I missing something here, or is there something I need to do to get my data at the required sampling rate?

Below is AnalogReadSerial code I used for reference:

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  delay(1);        // delay in between reads for stability
  • 1
    record the value of millis() before and after int sensorValue = analogRead(A0); ... then print the two values
    – jsotola
    Commented Jan 17, 2022 at 16:13
  • @jsotola I used micros(), and it takes 116 microseconds. Commented Jan 17, 2022 at 16:24
  • 115kBaud should actually be enough. 1000 Messages with about 6 bytes each (a 4 digit number and CR/LF) use 6000 bytes or 60000 bits/second. How fast can you get if you remove the delay?
    – PMF
    Commented Jan 17, 2022 at 18:34
  • 2
    Running your code on my Uno gives me 791.5 samples/s. Maybe your laptop is too slow to cope with the data rate? Commented Jan 17, 2022 at 19:39
  • Rookie mistake from me, I had to accordingly adjust the baud rate of my laptop's USB port using ssty because the default was 9600. Right now, I am getting data at a rate similar to yours @Edgar Bonet, which is better but still a little bit shy of the required rate. @PMF your calculations make sense and this baudrate should be within my laptop's and Arduino nano's limits, which is still confusing to me. I will remove the delay and check if that makes any difference. Commented Jan 18, 2022 at 14:23

1 Answer 1


As I said in a comment, your code on my Uno gives me 791.5 samples/s. This is about 1263 µs per sample:

  • about 110 µs for analogRead(), including 104 µs for the conversion proper
  • presumably 1000 µs for delay(1)
  • 153 µs for the rest of the code, mostly formatting sensorValue in ASCII

According to these timings, if it were not for the call to delay(), the Arduino should be able to complete the loop in one millisecond, and still have 737 µs to spare. The simplest way to achieve this is to follow the Blink Without Delay strategy:

void loop() {
    static uint32_t last_conversion_time = micros();
    if (micros() - last_conversion_time >= 1000) {
        last_conversion_time += 1000;

This does give me 1000 samples per second. Note that last_conversion_time is updated by adding 1000 µs rather than setting it to micros(), so this is actually a variation on the Blink Without Delay strategy. Updating last_conversion_time in this fashion ensures that whenever the program gets late and misses the exact microsecond it wanted, the small timing errors do not accumulate.

For the maximum possible timing accuracy, it would be more appropriate to trigger the ADC by a timer, but that approach is more complex and requires carefully reading the datasheet of the microcontroller.

  • I would not call it BlinkWithoutDelay strategy. It is different. It would be better to initialize last_conversion_time with micros() so it doesn't have to catch up with 1ms increments the time lost in setup() .
    – Juraj
    Commented Jan 18, 2022 at 21:09
  • @Juraj: I edited the answer to account for your comments. I would usually prefer letting last_conversion_time be initialized to zero, unless setup() is really slow (not the case here): this saves the cost of a guard variable and a test at each loop iteration. But then, maybe I tend to micro-optimize too much... Commented Jan 18, 2022 at 21:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.