ADC , result not accurate

i am trying to read the battery voltage of the car i am controlling, but the output is not correct when i recheck it with the multimeter.

i know so because it is above the voltage it can be 13.2 is coming as 14.5 and 4.9 as 5.2.

v_lifepo4=analogRead(battery_pin); v_lifepo4=v_lifepo4*0.01464; v_buck=analogRead(buck_pin); v_buck=v_buck*0.009765;

the constants i am using are correct , i know so because i used another arduino to check the voltage which shows the correct voltage.

what could be wrong ?

You have some interesting conversion factors in your code snippet. Post the whole code, then it may be clearer what voltage reference you are using.

The readings of the ADCs are always relative to the Vcc (usually 5V) if not configured for AREF. So if your Vcc varies your readings of the ADC will change appropriately. How stable is your Vcc? Do you use the standard voltage regulator of the Arduino or an external stabilised power supply?

In fact, your scaling down resistors will also introduce an extra error because they are not 0% tolerance so, in fact, you should calibrate your entire system, by feeding it a known voltage in the range you want to measure and seeing what value you read from the ADC - from this you can "correctly" read any other voltage.

Accuracy could be affected by output impedance of the source and wiring, can you post a drawings of your hardware set-up?

you may smooth readings with a running average - -

Hi, Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.,148850.0.html then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

i know so because i used another arduino to check the voltage which shows the correct voltage.

What was the model of the Arduino that showed correct voltage and what was the model of the Arduino that gives the error.

How have you worked out your conversion equations?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :)

code is a little big (its attached) , this is the only part where i read the voltage apart from this i have just defined these two pins as input
#define battery_pin A3
#define buck_pin A2
pinMode(A2, INPUT); // buck input
pinMode(A3,INPUT); // battery input

the conversion factor is due to the voltage divider ,
for battery it is … +__660K____A3____330K____Gnd
so 5*3/1024

for buck it is +_____330K____A2_____330K_____gnd
so 5*2/1024

i thought the resistors are way to big to allow the ADC to draw some current , but then i tried using another arduino just to measure the voltages after setting the conversion time to max to get better results , which i got so i made the same modification in the arduino on car but still same readings :frowning: .

i also thought that this could be due to the fact that i am powering the arduino using a buck converter.
( buck converter use a switching transistor with inductor in series and turn it on and off depending on the required voltage , so it is pulsating DC , though multimeter will show constant output … a oscilloscope wil not show constant output .)
i would also like to mention that i am giving the voltage at 5v , rather than Vin.

so i connected it with the usb supply from laptop which did modify the output but it further increased it by 0.2 , 0.3 rather than decreasing it ( actual value is 0.2 -0.4 less than what i m getting ).

i don’t have a coding background , so sorry if code is not neat.(put these three files in a folder named “carv2__oncar” , there are 2 “_” underscores )

carv2__oncar.ino (3.52 KB)

input_processing.ino (1.24 KB)

processing.ino (3.9 KB)

OK. It looks like you are using Vcc (5volts) as reference.
Google for “Arduino secret voltmeter” where you will see examples of using the internal voltage reference of the processor. On an ATmega328p (like in the Uno) there is an (approximate) 1.1 volt reference which you should calibrate once, and then use the derived conversion factor in your code.

Those resistors are pretty big, may be better to use 10-50k values but your current through them (which is basically wasted) goes up of course.

If you have 5% tolerance resistors, you can get up to 10% difference in readings between the two. Your 10% difference for the battery and 6% difference for the buck converter is a bit high, but can be explained this way.

Then the buck_pin: are you here trying to measure the voltage that's powering your Arduino itself? By default Vcc is used as reference for your ADC so you will see the same reading no matter what that voltage really is, as you're referencing to itself. Your resistor divider suggests you use the default reference, as the built-in reference is 1V so your input must be 0-1V when using that.


the conversion factor is due to the voltage divider , for battery it is ... +660KA3330K__Gnd so 5*3/1024

for buck it is +__330KA2_330K__gnd so 5*2/1024

As @wvmarle has said, your divider values are too high, the input impedence of the AtoD will be having an effect on the reading. Go down by a factor of at least 10, should show an inprovement, also a 0.1uF capacitor on each analog input to gnd to bypass any noise will help to. Tom.. :)