Why am I observing oscillations in my analogRead data stream?

My overall goal is to repeatably read three analog voltages using a Bluno Beetle (Bluno_Beetle_SKU_DFR0339-DFRobot) and send these values to my phone using a simple BLE terminal app. The voltage signals will always be below the supply voltage. I plan to sample the three voltages ten times at 30 second intervals, store that data into an array, then Serial.print those arrays all at one time every five minutes. In creating some test code that samples at intervals in the range of 100 milliseconds to 1 second I notice that the values jump around in a very regular pattern. For a consistent voltage source, I just used two 1 Mohm resisters to create a voltage divider, so I have test points that measure 3.321V and 1.591V (ORANGE) with a Fluke 116 multimeter. I used this script to read pin A0 (BLUE) and obtain this voltage data versus time:
IMAGE 1
Orange is DMM measurement, blue is Arduino Uno. This looks great, really stable. When I switch to the voltage divider I measure 1.591V on the DMM. Measured voltages versus time have a little oscillation.
IMAGE 2
That could be filtered passively and is not bad for my application. But when I run the exact same script on the Bluno Beetle the oscillations are much worse! I'd like to better understand why that is and what can be done to limit this?
The following data (same script) is from the Bluno Beetle (BLUE) where the DMM reads 1.013V (ORANGE).
IMAGE 3
The oscillation pattern is similar at the higher voltage, as shown below.
IMAGE 4

The script for this data is as follows:

void setup() {
  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
}

// the loop routine runs over and over again forever
void loop() {
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.0);

  Serial.println(voltage);
  delay(100);
}

I apologize for such a long post. I feel like I'm missing something fairly obvious. Thanks for the help.

Oh one more thing, the same patterns appear versus time with longer delays, like 10s of seconds.

My first guess is the power supply is not stable.

So now I ask, how are you powering the board. My guess is a computer. If a laptop, disconnect the laptop power adapter and run on the batteries for a test.

Do you have access to a different computer. Would be a good test to see if it changes.

In general a 500k ohm divider (2 x 1 meg ohm is approx = 500k) should have a capacitor at A0 to ground (both as close to the board connections as possible.

Read the ATmega328P data sheet section on the ADC - particularly the input impedance section. Your divider resistor values are off by a factor of ~100. If you really want to use such high values you need a capacitor from the junction to ground to hold the voltage and then read it at a rate much lower than the time constant for the RC of the divider.

What are you sensing? What is connected to A0?

Hi oldcurmudgeon - you are spot on, thank you. I added a 100 nF cap between the V test point and GND and now both the Uno and the Bluno Beetle read stable values.

Thanks JohnRob, I've tried a few different power supplies, laptop battery, battery banks, they all had the same issue. Seems like it was an impedance issue with the ADC.

The only problem left is that you are now measuring a voltage with the potentially unstable 5volt laptop supply as reference. When that USB supply varies 5%, so will your voltage readout.

You should dial down the source voltage to 1volt with your voltage divider,
and switch to the stable 1.1volt Aref in setup().
analogReference(INTERNAL); // switch to 1.1volt Aref
Leo..

Of course then you have to calibrate for the internal reference. It is relatively stable but the value is 1.0-1.2 volts. The 1.1 volts is a typical value. Remember the old saying "design with typical values and you will typically fail" :-).

Great point Wawa, thank you. I have incorporated the internal 1.1V AREF in my code.

Each analog sensor will have a calibration, so if across multiple sensors the AREF ranges between 1.0-1.2V I should be ok. There is some post processing of data that will be occurring once the Bluno beetle sends the data via BLE to a phone app.

Calibrating once, or constant instability. Take your pick.
My Arduinos are all about 1.075volt.
If you use that value without calibrating, then you could already be closer than ~5volt USB.
Leo..

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