analogRead() reading non-existent fluctuation?

Hi, I'm currently working with a 100psi MSP 340 pressure transducer.

I believe I'm using the code 2 model which has 4 wires, red for 5V, black for gnd, green for output plus and white for output minus. I'm currently taking the difference between the two voltages which should be a range from 0-100mV.

int green= A1;
int white = A0;
                       
int valuePlus = 0;  
int valueMinus = 0;

void setup()
{
  Serial.begin(115200);          
}

void loop()
{
  delay(500);
  analogRead(green);
  
  delay(50);
  valuePlus = analogRead(green); 
  
  delay(50);
  analogRead(white);
  
  delay(50);
  valueMinus = analogRead(white);
  
  Serial.print(valuePlus);  
  Serial.print(", ");
  Serial.print(valueMinus);  
  Serial.print(", "); 
  Serial.println(valuePlus-valueMinus); 
  
}

The analog readings I get from both lines fluctuate between 507 and 508 with some readings of 506 and 509. I expected some fluctuation and noise from the sensor, however, when I hook up a multimeter and actually measure the difference in voltage, it is 0.288mV +/-0.001mV. I'm a little confused because I haven't touched the AREF pin so it should be 4.9mV per tick so I thought that small fluctuation would be lost in the resolution.

If what I think is right,
508=>2.4843V
507=>2.4892V
but the multimeter reads 2.4884 and 2.4881. I don't mind offset, but that difference of about .0003 shouldn't show up on the arduino analogRead right?

I included delays for possible issues with ADC muxing but that doesn't seem to have changed anything. I also tried capacitors to ground but I don't think the sensor is noisy. I think this could be an arduino issue, does anyone have any ideas? Thanks

From the data sheet:

  1. Analog-to-Digital Converter 23.1 Features
    23.2 Overview
    • 10-bit Resolution
    • 0.5 LSB Integral Non-linearity
    • ± 2 LSB Absolute Accuracy

I wonder if the +/- 2 LSB accuracy might account for the error.

-br

Some questions first. Do you have a DMM that is actually certified to make readings that precise? Have you looked at your 5V rail? It's not 5.00000V and the ADC works from that. An ADC is almost always going to have the last bit toggling as you read it over and over. It's the nature of how the ADC works. It's just going to bounce the bottom bit, there's extra precision possible from that. Are you taking multiple readings and averaging them? I don't understand why 507 should be a higher voltage than 508. Everything looks within specs to me.

Hi, thanks for the replies. I forgot to mention it is an Arduino Uno.

That was a mistype, 507 is supposed to be 2.4843V and 508 is 2.4892V. I'm using the Agilent 34401A Digital Multimeter which I think should be ok for that, I'm not sure. You're right though, I recall testing the 5V rail and it was something like 5.00011V. I was going to average the numbers but I was just confused because I didn't think there would be any fluctuation. I think I'm going to put in an instrumentation amplifier with a high gain so the the last bit toggling won't affect the reading.

Devices always have some margin of error that you may or may not be able to do anything about. As the other poster said, Atmel outright admits that you should expect 2 LSBs of noise. I'm sure that the pressure transducer is the same way, it would be in the datasheet.

There is also some debate whether you divide the 5V by 1024 or 1023. Different manufacturer of ADCs will tell you different things. The reason being that there are only 1023 sections in the ladder (between the 1024 rungs so to speak).

On top of that, there is going to be some amount of supply ripple present no matter how much you filter it, unless you use batteries of course. And finally, there is internal noise in the chip when the peripherals are powered up. There should be some documentation available somewhere from Atmel that tells you how to minimize noise during an ADC conversion, including stopping clocks. All in all, I'd say you were sitting pretty with a very low noise level. Like I said, average several readings to get a better result. Also I would just build the hysteresis into the software and skip the instrumentation amp as I don't think there is any other way that you will rid yourself of toggling in the last bit, short of just tossing it out anyway.

You probably need low-pass filtering on the sensor inputs - something in the range 1nF to 10nF to ground for both
green and white wires ought to help - the leads to the sensor may be picking up noise, the sensor itself may
be noisy.

Multimeters use integrating ADCs so they effectively low-pass filter down to 1Hz or less bandwidth - the ADC on
the Arduino has a bandwidth more like 10kHz.

The solution is here: http://forums.adafruit.com/viewtopic.php?f=24&t=11597 (a software solution) :wink:

!!Code snippet
analogRead(A0); // dummy read to discharge ADC
delay (20); // wait a little
analogRead(A1); // now hook up ADC to the channel we really want to read
delay (20); // doze a little
temp = 100*(analogRead(A1)*5/1025 -0.5); // now read once more 
!!End of code snippet

here you can also adjust your sensors readings

http://hacking.majenko.co.uk/making-accurate-adc-readings-on-arduino

Are you powering the Arduino via the USB cable? USB power is not stable, it fluctuates quite a lot. If you can't run the Arduino from external power instead, then at least connect capacitors between each of the 2 analog inputs and ground (I suggest 0.1uF) and between the Aref pin and ground (e.g. 10uF).

You can expect the ADC reading to fluctuate between two adjacent values even with a very stable supply.

Hi afremont,
I always thought that counting started at "0" 0 to 1023 is 1024! so we call it 1023. But I agree that all sensors and ADC's etc have a bit of wobble on the LSB's. And power supplies are something else, with mains hum and picking up noise, etc.

Well that was just my little bit.

Regards
Mel.