analog readings incorrect and fluctuate, even with running average.

Hi. I am hoping this is the right place to post this... if not please direct me.

I have a whole other setup and code set for this project, but I have put all that on the backburner and have stripped everything down just to try to pin down this issue.

Currently all I am trying to do is take readings from a 2.5V reference, averaging 25 measurements over a span of 1.25s . The averaged analog output is roughly 254, or about 1.24V, while my multimeter reads 2.50V . The same thing happens when try to read my AD22100 temperature sensors, they read at about 1.3V while my multimeter puts them at ~1.92V, which is exactly where they should be at this temp.

I've tried looking at the raw data without averaging and the error is not in the averaging... well, at least not only.

Right now I am running everything off the board 5V supply, but before I was using a regulated 5V 1A supply for the sensors and the reference.

I am new to arduino so I figure it might be something obvious I am missing, or maybe I got a lemon.

Any ideas? Code supplied below for reference.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int arraysize = 25;
char sensorPin;


void setup(){
  


  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Vref:");
}

//Function - Read and average-------------------
int s_readAvg(int sensorPin){
  int i;
  int s_read = 0;
  int s_Avg = 0;

  for (i = 0; i < arraysize; i++){
    s_read = s_read + analogRead(sensorPin);    // sensor on analog pin #sensorPin
    delay(50);
  }
  s_Avg = s_read / arraysize;    // average
  return s_Avg;
}

  
  
void loop(){
 

  float sensorVoltage; 
 
 
  //Read voltage reference and average over 25 readings
  sensorPin = 'A5';
  sensorVoltage = s_readAvg(sensorPin);
  delay(10); 



  //Correct for 2.5V being read as ~1.3
//    sensorVoltage = sensorVoltage*1.9768;

    Serial.print("\t ref: ");
    Serial.println(sensorVoltage);
  
    
    delay(100);

 
    
//-------------LCD Output-----------------------------
    lcd.setCursor(0,1);
    lcd.print(sensorVoltage,0);



}

Thank you for a small sketch to get to the problem.
During development it is normal to have maybe 5 test sketches.

The function analogRead() uses a reference voltage.

The internal reference of 1.1V is independent of the 5V.
However, the default reference is the 5V, and if the 5V fluctuates, so will analogRead().

Your number of samples is 25, and you add everything to an integer.
25 * 1024 = 25600. That is okay, it will fit in an integer.

The pin A5 is not the text 'A5', but just A5.
You declare sensorPin as a character and assign the value later in the sketch.

char sensorPin;         // not preferred
...
sensorPin = 'A5';       // not okay, should be just A5, without '
sensorVoltage = s_readAvg(sensorPin);

A pin is preferred to be declared as "const int". Can you change it into this:

const int sensorPin = A5;
...
sensorVoltage = s_readAvg(sensorPin);

That should make it work.

Thank you for your response!

I made the changes you suggested, and it certainly changed things, but I am still getting strange results. Now the 2.5V reads at 839 or 4.1V. I also played around with changing the arduino's reference between DEFAULT (5V) and INTERNAL (1.1V). Default ref makes it read 4.1V while the 1V1 makes it read 5.0V. It seems like all my references are offset somehow.

I will say the readings are nice and steady, though, so that's an improvement.

ninja edit: Also, now if I put the pin at the midpoint between two resitors from rail to rail, it reads pretty close to right. Likely my external reference is borked.

When you measure at the Arduino pin with a multimeter, and you read 2.5V.
Then it is impossible that the Arduino reads 839. That's not possible, no way.
Did you connect the grounds ?
Can you try a single analogRead(), without the averaging ?
Or did you connect AREF to something ?
Do you use a breadboard ? those can have bad contacts.

Do you have another Arduino board to test ?

It would be nice to have a completely different Arduino board, and do a different test:
You could try with a 1N4148 diode (or two in series) and a resistor of 4k7 to 5V, and measure the forward voltage of 0.6V (or 1.2V), and convert it into temperature. I can get 3 degrees Celsius accuracy with two diodes.

When you measure at the Arduino pin with a multimeter, and you read 2.5V.
Then it is impossible that the Arduino reads 839. That's not possible, no way.

Well, Unfortunately that is very much the case.

Did you connect the grounds ?

When I was running the board and the breadboard off the two separate supplies, I did not link the grounds. I considered it, but I was worried about damaging the board. As of right now, everything is running off the arduino supply, so the rails are the same all around.

Can you try a single analogRead(), without the averaging ? Or did you connect AREF to something ?

I did, the values show up much the same, fluctuating from 838-840. AREF is clear, NC.

Do you use a breadboard ? those can have bad contacts.

I am using a couple daisy-chained solderless breadboards, and they do have numerous contacts which are worse than worthless. However, the values do not change when I connect the leads directly to the wires or pins, which leads me to think the readings are genuine.

Do you have another Arduino board to test ?

It would be nice to have a completely different Arduino board, and do a different test:
You could try with a 1N4148 diode (or two in series) and a resistor of 4k7 to 5V, and measure the forward voltage of 0.6V (or 1.2V), and convert it into temperature. I can get 3 degrees Celsius accuracy with two diodes.

By another board, do you mean another Uno chip? I actually do have a handful of spare chips. I should switch it out and try again. The test you mentioned could be informative, but unfortunately for my purposes I bought sensors that are good to +/- 0.5degC, which I need to be able to publish my results. I am hoping I can go back to using those.

I will switch out the chips when I get home and try that. Thanks for continuing to help with this issue!

It is not to measure the temperature, it is to do something completely different. If that works, you have a starting point. I mentioned the 3 degrees just for fun, to indicate that the analogRead() can be accurate.
If your chip is damaged, it is damaged in a weird way. But I can't think what else could be the cause.

You ever have one of those times when you feel like maybe you shouldn't tell people what was wrong, because if that was ever brought up in, say, a courtroom environment it would bring your credibility into such question that people would wonder how you tied your shoes in the morning without drooling on them?

I plugged the rails in backwards when running off the board supply.

It looks like everything is working now, even after I rolled back some of the changes I made to the code in this process. I think part of the problem was that I never declared the internal reference, and I also put in some capacitors to smooth out any voltage ripples, and connected the ground rails.

Thank you so much for your help!

Thanks for sharing. We have all been there.
Staring at a circuit for hours, and someone walking by pointing at a wire that is wrong.
Nothing is damaged ? That's very lucky.