Problem in Measuring DC Input Voltage by Analog Pin

Hello all.

I am trying to make my Arduino to work as an online multimeter. At the beginning, I'm trying to make it a voltmeter. I'm simply trying this tutorial: "http://tiny.cc,93515".

I've done exactly the same as the tutorial I'm following, with three exceptions:

  1. I'm not using an LCD monitor.

  2. I'm using R1 = 25 kilo-ohms and R2 = 5 kilo-ohms.

  3. I'm trying to make it an online voltmeter, so there is an Ethernet shield attached to it.

The problem is, whenever I'm giving about 3-4 volts DC input to the circuit, I'm watching on the serial monitor that the Arduino has measured 10-11 volts! When the input voltage is 10-11 volts, the serial monitor shows 16-17 volts. Whenever I give the maximum input of 27 volts (my power source is old, so does not reach the 30 volts maximum), the serial monitor is showing 28 volts!

So, I think that there is an offset in the ATmega328 which I need to remove.

Could anyone please help?

Thanks in advance.

Sorry, I typed the wrong link.

Here's the actual link: http://tiny.cc/93515/.

Did you replace the values of R1 and R2 in the sketch, where indicated, with the values that you actually have? Did you measure Vcc (The default analog reference) and put that value in the sketch where indicated? I wired up a breadboard with 4.7K and 22K resistors (5K and 25K are not standard values) , measured Vcc (4.88V), modified the code as shown and get reasonable readings from 0 to 12 volts (I don’t have a higher supply available). I also put a 0.1 ceramic cap from A0 to ground to filter noise a bit.

EDIT also you changed the ratio from about 10 to 1 to about 5 to 1 so the highest safe voltage to measure is about 25V. Over 25V the input will be too high.

int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 22000; // resistance of R1  -see text!
float R2 = 4700; // resistance of R2  - see text!
float Vcc = 4.88 // set for default analog reference
int value = 0;
void setup(){
  pinMode(analogInput, INPUT);
  Serial.begin(9600);
  //lcd.begin(16, 2);
  //lcd.print("DC VOLTMETER");
}
void loop()
{
  // read the value at analog input
  value = analogRead(analogInput);
  vout = (value * Vcc) / 1024.0; // see text
  vin = vout / (R2/(R1+R2));
  if (vin<0.09)
  {
    vin=0.0;//statement to quash undesired reading !
  }
  Serial.print("voltage = ");
  Serial.println(vin);
  //lcd.setCursor(0, 1);
  //lcd.print("INPUT V= ");
  //lcd.print(vin);
  delay(500);
}

Check the resistors or their values in your code. Your divide ratio is about 0.167 but your results are about double. List some specific results, not ranges.

Begins to verify your wiring before thinking about the Arduino or the code.
Measure actual voltage with a voltmetrer.

Warning : an atmega is not as precise as a "real" voltmeter.
You must take into account several factors. Everything is explained in the datasheet of the microcontroller that you can download from the manufacturer: ATMEL.

groundfungus:
Did you replace the values of R1 and R2 in the sketch, where indicated, with the values that you actually have? Did you measure Vcc (The default analog reference) and put that value in the sketch where indicated? I wired up a breadboard with 4.7K and 22K resistors (5K and 25K are not standard values) , measured Vcc (4.88V), modified the code as shown and get reasonable readings from 0 to 12 volts (I don’t have a higher supply available). I also put a 0.1 ceramic cap from A0 to ground to filter noise a bit.

EDIT also you changed the ratio from about 10 to 1 to about 5 to 1 so the highest safe voltage to measure is about 25V. Over 25V the input will be too high.

int analogInput = 0;

float vout = 0.0;
float vin = 0.0;
float R1 = 22000; // resistance of R1  -see text!
float R2 = 4700; // resistance of R2  - see text!
float Vcc = 4.88 // set for default analog reference
int value = 0;
void setup(){
  pinMode(analogInput, INPUT);
  Serial.begin(9600);
  //lcd.begin(16, 2);
  //lcd.print(“DC VOLTMETER”);
}
void loop()
{
  // read the value at analog input
  value = analogRead(analogInput);
  vout = (value * Vcc) / 1024.0; // see text
  vin = vout / (R2/(R1+R2));
  if (vin<0.09)
  {
    vin=0.0;//statement to quash undesired reading !
  }
  Serial.print("voltage = ");
  Serial.println(vin);
  //lcd.setCursor(0, 1);
  //lcd.print("INPUT V= ");
  //lcd.print(vin);
  delay(500);
}

Thanks a lot for the helpful tips. Well, I didn’t mesure VCC. Could you please tell me how to measure it? Then I can give your suggestions a try.

Measure the 5V to ground. On an Uno that is Vcc (positive supply voltage). You said ATmega328 so I assume an Uno. Correct me if I am wrong and do not use that circuit. CAUTION: do not apply over 25V with the circuit in my post. You will need to change the resistor divider ratio to measure higher voltages.

groundfungus:
Measure the 5V to ground. On an Uno that is Vcc (positive supply voltage). You said ATmega328 so I assume an Uno. Correct me if I am wrong and do not use that circuit. CAUTION: do not apply over 25V with the circuit in my post. You will need to change the resistor divider ratio to measure higher voltages.

Yes I'm using Arduino Uno.