arduinoi2cspianalog-digital-converter

Computation during analogRead on Arduino


The Arduino A/D converter takes about 0.1ms according to the manual. Actually, my tests show that on an Uno I can execute about 7700 per second in a loop.

Unfortunately analogRead waits while the reading is being performed, making it difficult to get anything done.

I wish to interleave computation with a series of A/D conversions. Is there any way of initiating the analogRead, then checking the timing and getting the completed value later? If this needs to be low-level and non-portable to other versions, I can deal with that.

Looking for a solution that would allow sampling all the channels on an Arduino on a regular basis, then sending data via SPI or I2C. I am willing to consider interrupts, but the sampling must remain extremely periodic.


Solution

  • Yes, you can start an ADC conversion without waiting for it to complete. Instead of using analogRead, check out Nick Gammon's example here, in the "Read Without Blocking" section.

    To achieve a regular sample rate, you can either:

    1) Let it operate in free-running mode, where it takes samples as fast as it can, or

    2) Use a timer ISR to start the ADC, or

    3) Use millis() to start a conversion periodically (a common "polling" solution). Be sure to step to the next conversion time by adding to the previously calculated conversion time, not by adding to the current time:

    uint32_t last_conversion_time;
    
    void setup()
    {
       ...
      last_conversion_time = millis();
    }
    
    void loop()
    {
      if (millis() - last_conversion_time >= ADC_INTERVAL) {
        <start a new conversion here>
    
        // Assume we got here as calculated, even if there
        //   were small delays
        last_conversion_time += ADC_INTERVAL;  // not millis()+ADC_INTERVAL!
    
        // If there are other delays in your program > ADC_INTERVAL,
        //   you won't get back in time, and your samples will not 
        //   be regularly-spaced.
    

    Regardless of how you start the conversion periodically, you can either poll for completion or attach an ISR to be called when it is complete.

    Be sure to use the volatile keyword for variables which are shared between the ISR and loop.