1
votes

I am using arduino Uno to read voltage from A0 pin with simple 1/3 resister divider (5v applies to a voltage divider, and A0 gets 1/3 of 5v). There is a relay connected to D1 pin.

(My eventual goal is to measure 15v, that's why using voltage divider to diagnose the problem)

I noticed that when relay is on, the A0 read is higher than it should be. I am not sure what's the cause, and like to understand it.

Description about the circuit:

A0: analog pin used to measure voltage.

D1: a digital pin used to control a relay.

Resistor divider: R1 = 2k, R2 = 1k. R1 connects to 5v (arudino Uno 5v output). A0 is connected to R2, therefore, A0 should get 1/3 of 5v, which is 1.67v.

Few measurements to diagnose the problem:

Vmesaure_all: a manual voltage measure on R1 + R2.

Vmeasure_r1: a manual voltage measure on R2 only, which is input voltage of A0.

Vcode_r1_A0: arduino A0 analog read.

A)Relay is off:

Vmeasure_r1=1.67v (1.67 *3 = 5.01)

Vmesaure_all=5.03v

Vcode_r1_A0=339 (339 * 3 = 1017)

All above makes sense.

B) Relay is on:

Vmeasure_r1=1.63v (1.63 * 3 = 4.89v. OK. Makes sense as it is almost same as Vmesaure_all)

Vmesaure_all=4.91v (Relay is a load, it makes voltage drop on if measuring voltage of R1+ R2. I think it is expected)

Vcode_r1_A0=345 (why higher than 339, which is relay off A0 read???)

I could not explain this. If use this value to calculate voltage on R1 + R2, you will get higher voltage (the voltage to be measured), compared with relay off.

I would expect Vcode_r1_A0 to be < 339.

I did few experiments, andgot consistent behavior described above. Why?

1
This question appears to be off-topic because it is more about hardware than programming. Please try asking on Arduino. - hichris123
It might be related to software to calculate the voltage. It's just not sure now. - user3792705
His problem is fixed with a line of code, but also a couple of resistors. So it is half and half, software and hardware. - jdr5ca

1 Answers

2
votes

Yes, the numbers can make sense. The analog to digital converter (ADC) by itself is not an absolute voltmeter. ADC's have a reference voltage and are calculating the digital value relative to that reference voltage. The Arduino provides you choice of reference voltage via the function analogReference()

The default behavior is that analog reference is the supply voltage pin, which is nominally 5.0 V. But that leads to your problem:

If Vcc changes while the analog input stays the same, the digital value changes.  
If Vcc drops, the digital value will increase.

In other words, an ADC is only as accurate as its reference voltage.

The ATmega chips include a voltage reference that will not vary with Vcc. If you set the INTERNAL reference, then full scale 1024 digital is now 1.1 V.

analogReference(INTERNAL);
x = analogRead(A0);
// now x = 1024 is A0 = 1.1 V

Using this code, the digital value will be more accurate and not sensitive to Vcc. The tradeoff is that the full scale range is greatly reduced to only 1.1 V. To accommodate that reduced range, you need to add a voltage divider. Because you already intend to do that, you should use the internal reference and adjust the resistor values of your divider.

But, you are dropping Vcc by 0.1 V! Do you notice the chip is hot or a burning smell? Confirm that the current drawn by the relay coil is within the rating of the pin. Commonly, people use a transistor or driver chip (for example ULN2003) to power a relay load. Also beware that connecting inductive loads like relays and motors straight to digital pins tends to destroy those pins because of the flyback voltage when you turn off the coil.