Pages: [1]   Go Down
Author Topic: Arduino voltmeter calculations  (Read 1843 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 3
Posts: 111
Arduino rocks?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to use arduino with LCD as car voltmeter. I've got R1=33kohm and R2=15kohm resistors as voltage divider. So if voltage stays below 15V from alternator it wont break arduino by going over 5V(it is the Vmax for inputs?)

But i cant figure out the how to make it show voltage correctly. I've got R1 and R2 in A0.

I tried to do it with this http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1292921201 but i dont know the right formula for me.


I've got now
Code:
value = analogRead(A0);
vout = (value * 3.4)/1024.0;  //voltage coming out of the voltage divider
vin = vout / (R2/(R1+R2));  //voltage to display

But i think i need the right value to replace 3.4?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But i think i need the right value to replace 3.4?
Whatever value is connected to Vref.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Full Member
***
Karma: 3
Posts: 111
Arduino rocks?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You mean Ref-pin? Nothing? smiley-razz
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How about 5 then?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Full Member
***
Karma: 3
Posts: 111
Arduino rocks?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've tried that. But when fluke shows 6.9V at resistors, arduino shows 6.6V. Is it possible to make it accurate or do i just need to finetune that value? Or are 1% resistors just not right for it?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'd leave the 5V as it is (assuming the supply voltage really is 5V) , and check that the values of resistors plugged into the potential divider equation are correct.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Portugal
Offline Offline
God Member
*****
Karma: 6
Posts: 962
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Arduino adc is max rated for 5.5v, so 6.9v is good to kill it.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

He's right - I assumed when you wrote "at the resistors", you meant across the potential divider.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 216
Posts: 13664
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

15Volt  over 33K and 15K gives  max 4.7 volt over the 15K resistor.
As Vref is not connected it uses 5Volt from the Arduino Power supply - you need to measure this as between 4.9 and 5.1 reference voltage = 4% difference!

raw = analogRead(A0);

// raw = 0..1024    representing 0..Vref  volt

vout = 5.00 * raw / 1024.0;  // as Vref = 5.0 Volt (to be measured)

convert to car voltage;

voltageCar = (vout  / 15.000) * (15.000 + 33.000);  // or in short voltageCar = vout * 3.2:

Please fill in the resistors measured values .

The final code could become

Code:
// these defines have to be measured
#define VREF  5.10
#define R1 32767.0
#define R2 15140.0

float raw = analogRead(A0);
float vout = VREF  * raw / 1024.0;
float carVoltage = vout / R2 * (R1 + R2);  

// or in a oneliner
// float carVoltage = analogRead(A0) * VREF / 1024.0 / R2 * (R1 + R2);
// as VREF / 1024.0 / R2 * (R1 + R2); are all constants one could compact this to

carVoltage = analogRead(A0) * 0.01576; // used sample constants above.  
-- updated layout --
« Last Edit: June 02, 2011, 12:07:20 pm by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Full Member
***
Karma: 3
Posts: 111
Arduino rocks?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried to add measured values from resistors but its still off. Can this even be very accurate? I've changed a bit of R1 and R2 values and now im tenth off comparing to fluke. I think im satisfied with this smiley-razz

Thanks guys!
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 216
Posts: 13664
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The precision of tha ADC of the Arduino is 10 bit, in practice the last bit may be inaccurate. That means you have approx 500 steps for 0..15 volt ==> at best 1/30 volt precission = 0,2% . Assume the resistors have an accuracy of 1% . suppose VREF has an accuracy of 2%.

Then - float carVoltage = analogRead(A0) * VREF / 1024.0 / R2 * (R1 + R2); - would give an max accumalate error of
                                                    0.2% +     2%  +    0%     + 1% + 1% + 1%  = 5.2%

=> 15V * 5.2% = 0.8 Volt max error => so one tenth of is indeed very good.

Disclaimer not official error math, just an first order approximation.

One can improve the measurement by doing the AnalogRead multiple times:
Code:
float readVoltage()
{
  #define SAMPLES 3.0
  float rv = 0;
  for (int i=0; i< SAMPLES ; i++) rv += analogRead(A0);
  rv /= SAMPLES;
  return rv * 0.01576;   // average of 3 reads times the calculated constant.
}

If time is not an issue one can take more samples ...
« Last Edit: June 02, 2011, 12:29:46 pm by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: