Nano Every: subsequent analogRead() corrupts values

I am developing a six-channel AC-measuring using the Arduino Nano Every.
All six signals are 50Hz, fairly sinusoidal. These AC-signals are prepared using the current transformer ZMBT101b together with OPAMPs to shape them for the analog inputs of the Nano Every.

My plan is to read and store all 6 readings every 1ms in an array. And here I met my problem with the Nano Every: Subsequent use of readAnalog() as shown in my sketch does corrupt the values provided by analogRead()

/* 
 * IDE 1.8.7, Board Arduino Every or Nano
 * Sketch to demonstrate effect of consequent readAnalog()
 * ElekIng, 18.3.2024
 */

int const NumberOfSamples = 20;         
int const TLoop = 1000;           //1ms Loop-cycle time
bool sampling = true;       
int samples[NumberOfSamples];        
int count=0;
int i=0;
unsigned long time_now = 0;  


void setup() {
Serial.begin(9600);
count =0;
sampling = true;
}

void loop() {
    time_now = micros();
   if (sampling) {  // sampling rate 1ms for 50Hz almost sinusoidal signal
      samples[count] =  analogRead(A0); 
      samples[count] =  analogRead(A1); // out-commenting makes the difference!
      count++;
      if (count > NumberOfSamples) {
         count = 0;
         sampling = false;
       }
       while(micros() < time_now + TLoop){
       } // Wait until 1ms is over
    }
    else { 
       for (i=0; i<NumberOfSamples; i++)  {
          Serial.print(samples[i]);Serial.print(" ");
        }
        Serial.println(" ");
        sampling = true;
     }
} //loop

values with only one reading per 1ms

values with two readings per 1ms

Any help/workarround ist highly appreciated.
Thanks and greetings Peter

If the source impedance is too high, the ADC input sample capacitor does not have time to charge or discharge properly when switching channels. That will distort the readings, so consult and obey the manufacturer's recommendation on source impedance, as discussed in the processor data sheet.

After switching channels, many people find it beneficial to read the ADC twice and discard the first reading.

1 Like

This helps me to understand what is happening in the multi-channel ADC.
The input signal comes directly from the output pin of the OPAMP (LM358).
A1 is connected directli to GND.

For additional input, please post a complete schematic diagram of the experimental circuit (hand drawn is preferred), with pins, parts and connections clearly labeled.


For further input here my experimental schematic.

Thanks for posting the nice schematic diagram, but if analog input A1 is grounded, why are you reading it?

    samples[count] =  analogRead(A0); 
    samples[count] =  analogRead(A1); // out-commenting makes the difference!

The LM358 is an old design and is severely limited on common mode input voltage range (0 to Vcc-2) and output voltage swing, so it is a very poor choice for 5V circuits. I recommend the MCP600x series for low frequency circuits.

1 Like

Thank you for your help and your consideration regarding LM358.

Of course in the final schematic all 6 channels will be there and connected to the A0,A1,A2,A3 and A6,A7-Pins.

Thanks a lot. Peter

It is not a too high impedance of the voltage source but a too low one that produce a corrupted value of the first reading (in my sketch: A0), Today I made the following experiment: I disconnected the input A1 from GND and let this input open. Then the first reading is no longer affected by the following analogRead(A1). I tried this 10 times, Always same result. A1 connected to GND again corrupted value of previous A0.
I am not happy with this. This means that the analogRead() procedure has side effects not documented in the arduino reference. I have expected, that the procedure does not end before the apparatus is ready to measure another input pin.

Add a 0.1uF cap from A0 to ground and repeat your experiment. I'll wager a donut that your readings clear up.

1 Like

This has nothing to do with Arduino. That sort behavior is expected for MCU ADC hardware, and is discussed in the MCU data sheet. Your circuit is not giving the sampling capacitor charge enough time to stabilize.

1 Like

New experiment measuring four channels using analogRead():

Channel1 A0 sinusoidal voltage with VCC/2 offset
Channel2 A1 GND
Channel3 A2 VCC
Channel4 A3 GND
IDE 1.8.7

Timing of analogRead()'s and storing values in four arrays

After the measuring sequence the values are printed on the console. Then again measuring etc.

Findings
All my three exemplars 1. Arduino uno, 2.Nano and 3. Nano Every show exactly the same:
The first reading after 0ms is corrupted, the following readings from 1ms to 21ms are correct.

For my project I will discard the values between 0ms and 1ms. To get my 20 samples for a 50Hz-period I have to sample 21 times and discard the first one. This is my workarround for the moment.

Thanks again for the hint with the MCP600x. It's really better solution than LM358 for my project.

1 Like

I tried this. In my case it makes no difference.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.