Home | pfodApps/pfodDevices | WebStringTemplates | Java/J2EE | Unix | Torches | Superannuation | | About Us

Forward Logo (image)      

Read Analog values reliably without holding up the loop()

by Matthew Ford 15th January 2015 – corrected library include (originally posted 1st April 2014)
© Forward Computing and Control Pty. Ltd. NSW Australia
All rights reserved.

What is wrong with the Arduino AnalogRead()?

The Arduino langauge provides an AnalogRead() method to perform A/D coversions on the analog inputs A0 to A5 etc. The AnalogRead() method has two problems:-
i) AnalogRead() halts the main loop() while it waits for the A/D conversion to complete, typically 0.1mS to 0.2mS for each conversion.
ii) AnalogRead does NOT discard the first reading after changing the reference voltage. The Atmel datasheets for the micro-processors Arduino uses advises the user that the first A/D reading after changing the reference voltage may be incorrect and should be ignored.

The library available here solves both those problems. There are a number of other A/D conversion libraries available that use interrupts to report back when the conversion is finished. Using interrupts is an un-necessary complication and requires adding interrupt handlers and taking special care to access the results atomically. Using the polling approach is a much simpler and more straight forward.

Sample Code for Polling Analog Read

#include <elapsedMillis.h>
#include <pollingAnalogRead.h>
elapsedMillis batteryVoltsTimer;
int batteryVoltsInterval = 1000;  // the interval at which the battery volts is read

void loop() {
   checkBatteryVolts(); // call this every loop.  other loop code here

void checkBatteryVolts() {
  if (batteryVoltsTimer > interval) {
    batteryVoltsTimer -= interval; //reset the timer
    triggerAnalogRead(A0); // start another conversion
    // if the last conversion not finished 
    // or the value not read yet (by calling getAnalogReading()),
    // then calls to triggerAnalogRead() have no effect.
  if (isAnalogReadingAvailable()) {
    // conversion finished
    batteryVoltsReading = getAnalogReading(); // pick up reading
    //  Serial.print(F("  Reading:"));
    //  Serial.println(batteryVoltsReading);

In the above code, checkBatteryVolts is call every loop(). Once a second, an analog read on A0 is triggered. Every loop isAnalogReadingAvailable() is checked to see if the A/D conversion has finished and the reading is a available. When a new reading is available, it is stored in batteryVoltReading for later use.


Download pollingAnalogRead.zip to your computer, move it to your desktop or some other folder you can easily find and then use Arduino 1.5.5 IDE menu option SketchImport LibraryAdd Library to install them. If you are not using Arduino 1.5.5 IDE, or if you are updating a previously installed library, you have to manually unzip the zip file to your arduino/libaries directory. (Open the Arduino IDE File->preferences window to see where your local Arduino directory is).

Stop and restart the arduino IDE and under File->Examples you should now see pollingAnalogRead example.

Library Reference:


pollingAnalogRead for Arduino performs AnalogReads without holding up the main loop() and automically discards the first reading after the reference voltage is changed, as recommended by the Atmel datasheets.


void pollingAnalogReference(uint8_t mode) set the A/D reference voltage, see the Arduino AnalogRead() reference page for details. When a different reference is set this library automatically makes two A/D conversions and discards the first and returns the second.

bool isAnalogReadingAvailable()returns true when the A/D conversion has been triggered and has finished and a reading is available. It only returns true once after the A/D conversion completes.

void triggerAnalogRead(uint8_t pin)starts a new A/D coversion but only if the last conversion has finished and isAnalogReadingAvailable() has been called and returned true.

int getAnalogReading() – get the last A/D conversion result. This can be called more then once. The latest A/D conversion value is returned.


The pollingAnalogReadTest illustrates how pollingAnalogRead continues to process the loop() while waiting for the A/D conversion to complete.

The Serial monitor shows the number of times loop() is executed between readings. If you use the standard AnalogRead() the loop count would be only 1 for each read.

pfodDevice™ and pfodApp™ are trade marks of Forward Computing and Control Pty. Ltd.

Forward home page link (image)

Contact Forward Computing and Control by
©Copyright 1996-2015 Forward Computing and Control Pty. Ltd. ACN 003 669 994