voltmeter wont read 0v

Just getting started here, and I am having trouble getting my voltmeter project to read 0v my code is as follows (copied and modified from the net):

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2); //set the LCD address to 0x27 for a 16 chars and 2 line display

//variables for input pin and control LED
  int analogInput = 1;
  int LEDpin = 13;
  int prev = LOW;
  int refresh = 1000;
  float vout = 0.0;
  float vin = 0.0;
  float R1 = 980.0;    // !! resistance of R1 !!
  float R2 = 987.0;     // !! resistance of R2 !!
  
// variable to store the value 
  int value = 0;
  
 
void setup(){

  // declaration of pin modes
    lcd.init(); 
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("I2C Voltmeter");
    lcd.setCursor(0, 1);
    lcd.print("Voltage: ");
    lcd.setCursor(13, 1);
    lcd.print("V");
  pinMode(analogInput, INPUT);
  pinMode(LEDpin, OUTPUT);
  
  // begin sending over serial port
  Serial.begin(9600);
}

void loop(){
  // read the value on analog input
  value = analogRead(analogInput);
  //Serial.print("value=");
  Serial.println(value);

  if (value >= 1023) {
    Serial.println("MAX!!");
    delay(refresh);
    return;
  }
  else if (value <= 0) {
    Serial.println("MIN!!");
    delay(refresh);
    return;
  }

  // blink the LED
  if (prev == LOW) {
    prev = HIGH;
  } else {
    prev = LOW;
  }
  digitalWrite(LEDpin, prev); 

  // print result over the serial port
  
  vout = (value * 5.0) / 1024.0;
  vin = vout / (R2/(R1+R2));
  
  
  //Serial.print("vout=");
  //Serial.println(vout);
  lcd.setCursor(9, 1);
  lcd.setCursor(9, 1);
  lcd.print(vin);
  Serial.print(vin);
  Serial.println(" volt");

  // sleep...
  delay(refresh);	
}

I use the serial monitor and it shows analogRead(0) is 0, and 0*5.0/1024.0 should equal 0
I’m sure to have missed something stupid here as I have little experience

Thanks in advance
Cory

KE7GKP: Sorry for the incomplete post it was early. I am just shooting for measuring the voltage onboard the Uno running from the usb port.

R1 and R2 are 1k resistors in a voltage divider circuit on a breadboard.

5v---R1----R2---GND (5v and GND are from Uno Board) I I pin1

Just 3 wires to the breadboard, and 4 to power and run the I2C LCD display from FleaBay. It shows 4.86v when plugged into the 5v and 3.21 when plugged into the 3.3v but retains the last reading when I plug pin1 to ground. The serial monitor reflects ADC value of 510 when 5v and 0 when GND but the display wont change. Reading 0v is not critical. Just scratching my head how a number divided by 0 doesn't trigger a 0 on the display. (If i use a common ground it also successfully measures AA,AAA,etc batteries) Thanks again 73's Cory N7FV

KE7GKP: Thanks again for the quick replies. I am powering the Uno from the USB port. Dumped the divider and the full scale readings work just fine.

Using the Serial Monitor 5v gave me 1023 3.3v gave 660 0v gave me 0 With the voltage divider: 5v the ADC reading is 510 3.3 gave me 330 0v gave me 0

Apparently its an LCD code problem as the maths work out correctly on the serial monitor. I'll do some more reading and see what I can come up with, as I must not be sending the right info to the display.

Thanks again for your help Cory

the only thing that I see in your code is a double setCursor.

  lcd.setCursor(9, 1);
  lcd.setCursor(9, 1);
  lcd.print(vin);
  Serial.print(vin);
  Serial.println(" volt");

As vin is a float you might add the decimals parameter: lcd.print(vin, 1); // default = 2

Furthermore I had an LCD that needed a delay() of a few millis to process the commands.

Can you tell what LCD you have - datasheet - ?

And a link to the LiquidCrystal_I2C library?

Does the library accepts floats? Have you tried

  lcd.setCursor(9, 1);
  int whole = vin;
  int decimal = (vin - whole)*10;
  lcd.print( whole);
  lcd.print( ".");
  lcd.print( decimal );
  Serial.print( vin);
  Serial.println(" volt");

Just for completeness, the code should be

  vout = (value * 5.0) / 1023.0;

Since there are 1023 steps from 0V to 5V, not 1024, but in practice it isn't important as the ADC error is a couple of LSBs.

MarkT: Just for completeness, the code should be

  vout = (value * 5.0) / 1023.0;

Since there are 1023 steps from 0V to 5V, not 1024, but in practice it isn't important as the ADC error is a couple of LSBs.

Actually, 1024 is correct (the reason I know is that I made exactly the same mistake a few weeks ago!). From the data sheet:

"The ADC converts an analog input voltage to a 10-bit digital value through successive approximation. The minimum value represents GND and the maximum value represents the voltage on the AREF pin minus 1 LSB."

Ah, it must be an R-2R ladder internally then...