AnalogRead gives value much higher than expected

First of all it’s my first post here so maybe I’ll have a bunch of format mistakes, sorry.

I’m using an Adafruit M0 to read a PH probe, it’s connected to the A0 pin and I need to use the analog reading to get the data.

So when it reads a value of 7ph it should show:

Analogread = 511.5
Voltage = 2.5V

But it gives me:

Analogread = 780
Voltage = 3.8V

I’m reading the A0 pin with a multimeter and gives me the correct reading, 2.5V and so with the arduino uno analog reading.

That’s my code:

void setup() {

  Serial.begin(9600);
}

void loop() {
  float sensorValue = analogRead(A0);
  Serial.print("AnalogRead: ");
  Serial.println(sensorValue);
  float voltage = sensorValue * (5 / 1023.0);
  Serial.print("V: ");
  Serial.println(voltage);
  Serial.println("\n");
  delay(5000);
}

Thank you in advance, and sorry for the mistakes in the post.

I'm not really familiar with the Adafruit MO, but apparently it runs at 3.3V which means a 3.3V ADC reference.

780 * (3.3 / 1023.0) gives me 2.51V.

The analogRead() returns an int not a float value.

Here is something you can try using a slight modification of your code.

void setup() {
  analogReference(EXTERNAL); // use AREF for reference voltage
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0);
  Serial.print("AnalogRead: ");
  Serial.println(sensorValue);
  float voltage = sensorValue * (3.3 / 1023.0);
  Serial.print("V: ");
  Serial.println(voltage);
  Serial.println("\n");
  delay(5000);
}

I am guessing Arduino Uno or similar. Since your Analog Input will likely only see a max of 3.3 volts as was mentioned in your setup code we added this line:

analogReference(EXTERNAL); // use AREF for reference voltage

Now connect the 3.3 volt out on your board to the AREF pin. This way your new analog reference becomes 3.3 volts so we also change:

float voltage = sensorValue * (3.3 / 1023.0);

Eventually you may want to think about averaging maybe ten samples and using a map function to get the readout in PH. That assumes a linear input as I have no experience with your sensor.

Ron

@Ron_Blain
On UNO, the IOREF pin connects to 5V, I think you mean the AREF pin.

JCA34F:
@Ron_Blain
On UNO, the IOREF pin connects to 5V, I think you mean the AREF pin.

Uh Oh, many thank you. I fixed it and yes the AREF pin.

Thank You
Ron

herbschwarz:
The analogRead() returns an int not a float value.

It does, but you can assign it to a float variable without any problems.

Yes, aarg. But the float variable uses very much more
memory than an int would use.

People have reported in the past that reading the analog input has a more stable reading on a second read like below.

float sensorValue = analogRead(A0);
  float sensorValue = analogRead(A0);
  Serial.print("AnalogRead: ");
  Serial.println(sensorValue);

DVDdoug:
I'm not really familiar with the Adafruit MO, but apparently it runs at 3.3V which means a 3.3V ADC reference.

780 * (3.3 / 1023.0) gives me 2.51V.

Exactly!
That is the very reason.

Whatever you end up getting , its worth having some means of calibrating within your software to get things spot.

I always try to stick with integer maths if you are dealing with an analog input , it’s easier to think you are getting more resolution/accuracy than you think by converting to a float .

zoomkat:
People have reported in the past that reading the analog input has a more stable reading on a second read like below.

That is only if you are using more than one analog input, and the ADC has to switch inputs. High impedance outputs (such as from a voltage divider) may cause the ADC take too long to settle, hence the second reading.

Your code example will give a "redefined" error from the compiler...

herbschwarz:
Yes, aarg. But the float variable uses very much more
memory than an int would use.

The program has to print the value as a decimal scaled to 5.0V. So, you have to create a float somewhere anyway. Unless you want to write custom output routines. Also I would not call 2 bytes "very much more".

aarg:
The program has to print the value as a decimal scaled to 5.0V.

Have you got a reason to "scale to 5V" since you are using a 3,3V chip?