analogRead second pin / second read wrong voltage

Hi,

I am going crazy at the moment since my analog pins are behaving strangely: I am trying to read a voltage from an analog Arduino Due pin using the following code:

float ReadVoltage(int Pin)
{
	return float(analogRead(Pin)) / 1023.0 * 3.3;
}

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

void loop()
{
	Serial.println(String(ReadVoltage(A0))+"V\t"+String(ReadVoltage(A1))+"V");
	delay(300);
}

If nothing is connected to both analog pins, I receive following values:

1.36V 1.90V
1.46V 1.70V
1.28V 1.67V
1.26V 1.61V
1.22V 1.64V
1.25V 1.58V
1.21V 1.63V

If I connect the 3.3V pin to analog pin 0 (pin 1 is not connected), the serial monitor shows following values:

3.30V 3.30V
3.30V 3.30V
3.30V 3.30V
3.30V 3.30V
3.30V 3.30V
3.30V 3.30V
3.30V 3.30V

Why do both pins read a voltage of 3.3V now?

If I connect the 3.3V pin to analog pin 1 (pin 0 is not connected), the serial monitor shows following values:

1.42V 3.30V
2.07V 2.76V
2.56V 2.74V
2.55V 2.76V
2.56V 2.73V
2.55V 2.75V
2.56V 2.74V

The first value of analog pin 1 is correctly 3.3V, then both seem to read random values. Why? This only works after a reset. If I connect the 3.3V pin to analog pin 1 while the program is running, I never read a voltage of 3.3.

This behaviour influences my readings, even if both analog pins (0 and 1) are connected:
Example:
I connect 3.3V to analog pin 0 and 2.0V to analog pin 1 and read A0 and A1 in the loop-function, I receive the following values:

A0: 3.30 //this is correct
A1: 1.98 //this is correct
A0: 3.30 //this is correct
A1: 3.30 //this is wrong, should be around 2.0V
A0: 3.30 //this is correct
A1: 3.30 //this is wrong, should be around 2.0V
(...)

Conclusion:

  • Just reading one analog pin in a single sketch/program just works fine as expected.
    The correct reading of a single analog pin is independent of the analog pin number. All pins work fine if only one pin is read per program.
  • Reading more analog pins in one single sketch/program fails.
  • The first reading of the analog pin with the greater number succeeds, the following ones fail and return the voltage of the pin having the lower pin number.
  • Switching the reading order (first reading the analog pin with the higher pin number) allows two readings of the analog pin number to succeed instead of only one (see previous point).
  • I can reproduce those issues on two Arduino Due boards.

Can anybody reproduce this issue and/or help me?

Thanks in advance.

Kind regards
Birk

I'm no DUE expert but if it is the same as the UNO there is only one ADC which is multiplexed so the readings are essentially done by the same hardware. What you can see is an echo of the previous reading.

(again no due expert)

Thank you for your reply.
What does that mean for me? How can I read several analog values then?

EDIT: I now added delays of 1 second in between the readings but there is no change in behaviour.

Try a short delay between reading analog inputs

float ReadVoltage(int Pin)
{
	return float(analogRead(Pin)) / 1023.0 * 3.3;
}

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

void loop()
{
	Serial.print(String(ReadVoltage(A0))+"V\t");  Serial.println(String(ReadVoltage(A1))+"V");
	delay(300);
}

That's what I have done:

float ReadVoltage(int Pin)
{
	return float(analogRead(Pin)) / 1023.0 * 3.3;
}

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

void loop()
{
	Serial.print(String(ReadVoltage(A0))+"V\t");
        delay(1000);
        Serial.println(String(ReadVoltage(A1))+"V");
	delay(1000);
}

But as I have already stated in my last post, this does not change the behaviour (except that the outputs are delayed).

I believe you are being tricked by assuming that an unconnected analog input pin will return a zero value. It won't as you will be reading a 'floating input pin condition' and the values returned from a analog pin with nothing wired to it are meaningless noise values.

Lefty

Thank you for your reply, but I know I won't read a zero value. My problem is that when something is connected, I receive random values. Only for analog pin 0 being connected, my values are correct (regardless of the values at analog pin 1).

Birk:
Thank you for your reply, but I know I won't read a zero value. My problem is that when something is connected, I receive random values. Only for analog pin 0 being connected, my values are correct (regardless of the values at analog pin 1).

Then I'm not sure of what you are seeing. If you have two analog voltages wired to two analog input pins and you have verified the two external voltages with a digital volt meter, what is the error reading on which pin? Is the external voltage being measured have a source impedenace of proper value? A Uno requires a source impedeance of 10k ohms or less, not sure what a Due requires.

I guess one test is to wire a single external voltage to be measured to both analog pins 0 and 1 and see if they measure the same?

Lefty

Try two reads on each pin, discarding the first reading.

Unfortunately, this does not work for me either. I have attached my circuit below.

Note that the IOREF-pin is equal to the 3.3V pin (according to the Fritzing platform). However, I still do not receive the expected values. Both values (at analog pin 0 and 1) return around 2.5V, which is right for pin 0 but pin 1 should return 3.3V. (The A0 and A1 pins are not connected in any means.)

I can reproduce this behaviour using two different Arduino Due controllers.

Can't anybody else reproduce this? I mean this should be a known issue.

Hi,

I know pushing is not desirable. But can anyone reproduce that issue using my code and/or circuit above? I would like to know if this is a failure of my two Arduino Due boards (which I consider really improbable). However, I cannot imagine that only one analog pin is supposed to be readable correctly since there are several ones.<

Obviously, a relay / a transistor might be able to workaround the issue. I would like to avoid using both since using a transistor I receive a voltage drop and relays unnecessarily use up financial resources.

Kind regards
Birk

When I try to compile your lines of program on IDE-1.0.5 I get errors :

ReadAnalogVoltage.ino:12:37: error: call of overloaded ‘String(float)’ is ambiguous

Maybe your code is too complex for the IDE and gives unreliable results.

Why don't you try the simple program from the examples /Basics/ReadAnalogVoltage
You can modify that program to read A0 and A1 both and see what readings you get.
Then you can conclude if you have a hardware or a software error.

Having now modified the analog basic analog read voltage example into:

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

void loop() {
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (3.3 / 1023.0);
  Serial.println(voltage);
  delay(1000);
  sensorValue = analogRead(A1);
  voltage = sensorValue * (3.3 / 1023.0);
  Serial.println(voltage);
  delay(1000);
}

I still receive the same results as before. Only the first reading of A1 is correct. The following readings of A1 return 3.3 which is correct for A0 only...
Reading only the pin A0 in one program works fine and reading only values from A1 in a single program works fine, too. The problem only occurs as soon as I want to read two analog pins in one sketch...

How is your Aref connected ?

When i try your code, my readings are not 3.30V but 2.18 volt but stable all the time.

when i change your line(s) :
voltage = sensorValue * (3.3 / 1023.0);
into
voltage = sensorValue * (5 / 1023.0);

my readings are 3.30 volt when the 3.3 volt is connected to either one of the analog inputs.

I cannot reproduce your erroneus result .
I suggest you try to avoid using analog input A1 because this input seems to be unreliable.
A microprocessor is a sensitive device so your A1 input might have become unreliable because of a static discharge or some other reason.

Then probably you are using a 5V based board, not an Arduino Due. Arduino Due pins are based on 3.3V, therefore I need to multiply with 3.3 / 1023. If I use pins A2 and A3, I am experiencing the same problem. A2 values are constantly correctly 3.3V whereas A3 value is only correct for the first reading. And I am having this problem on two Arduino Due boards.
My AREF is not connected at all so the reference voltage for the Arduino Due should be 3.3V.

Conclusion:

  • Just reading one analog pin in a single sketch/program just works fine as expected.
  • The correct reading of a single analog pin is independent of the analog pin number. All pins work fine if only one pin is read per program.
  • Reading more analog pins in one single sketch/program fails.
  • The first reading of the analog pin with the greater number succeeds, the following ones fail and return the voltage of the pin having the lower pin number.
  • Switching the reading order (first reading the analog pin with the higher pin number) allows two readings of the analog pin number to succeed instead of only one (see previous point).
  • I can reproduce those issues on two Arduino Due boards.

Example:
I connect 3.3V to analog pin 0 and 2.0V to analog pin 1 and read A0 and A1 in the loop-function, I receive the following values:

A0: 3.30 //this is correct
A1: 1.98 //this is correct
A0: 3.30 //this is correct
A1: 3.30 //this is wrong, should be around 2.0V
A0: 3.30 //this is correct
A1: 3.30 //this is wrong, should be around 2.0V
(...)

A0: 3.30 //this is correct
A1: 1.98 //this is correct
A0: 3.30 //this is correct
A1: 3.30 //this is wrong, should be around 2.0V
A0: 3.30 //this is correct
A1: 3.30 //this is wrong, should be around 2.0V
(...)

What and how are you supplying this A1 voltage (2.0) ? The output impedance of a voltage source can be an issue if it's too high a value.

I am voltage-dividing the 5V supply pin from my Arduino using two resistors (see an example configuration I have tried in the circuit I have attached some posts above).

Birk:
I am voltage-dividing the 5V supply pin from my Arduino using two resistors (see an example configuration I have tried in the circuit I have attached some posts above).

And what are the value of the two resistors? We need to determine the output impedance of this divider to see if it could be a factor in what you are seeing.

I can confirm the conclusions that Birk as made on two separate Arduino Due boards. One is real and the other is a close knock-off due (that one of my co-workers ordered from a less than trustworthy source). I just made a post about this and only found this post after making my post (Arduino Due analogRead() repeats itself - Arduino Due - Arduino Forum), go figure.

My best guess is that it is an error in the Arduino software in the ADC MUX selection portion of the analogRead() code for the Due. I still need to confirm this but I plan to pick the code apart tomorrow to see for myself unless I find an answer elsewhere first.

I was feeding the ADC inputs from a few potentiometers and I don't think impedance has anything to do with the issues I have been having since the total impedance is sufficiently high and a multimeter confirmed that I am not completely wrong.

I found the solution to the problem after some more searching and looking through the github repo of files. The issue is in how the ADC mux is used on the due and this has been fixed in the latest source if you download and build that yourself. The analogRead function was enabling a channel but then did not disable the channel that was enabled after completing the read. This is why the analog Read would always default to one pin over the others since it was looking at which channels were enabled to be read.

Go to git hub, download the source code, and build it yourself to resolve the problem. This will probably be resolved for everyone in the next beta release or when they decide to make the beta part of the stable main release.

1 Like