Reading and converting analog input for display to an LCD

Morning ! folks.

I’m using an Arduino and a 16 x 2 LCD to make a sketch that will measure the unknown value of a resistor. My 3 year old nephew decided to experiment on whether a multi-tester would float in an inflatable paddling pool, so I’m waiting for my new multi-tester to arrive in the mail. In the meantime, with a load of unknown value resistors to sort and store, I decided to write an Arduino sketch to measure their values.

I have one resistor, R1, whose exact value I know ( 9990 ohms ), so I set up the Arduino and the LCD so that the circuit would test the voltage division between the resistors, and use ohms law to calculate the value of the unknown resistor. I thought, technically, it should work.

However. when I run the sketch, using the known R1 value and a resistor whose colour bars indicate a similar value, I correctly get the Vout value at the divider ( approximately half of Vin ), but the resistance value of R2 is displayed waaaaaaay out.

For example, when I use a resistor whose colour bars indicate R2 = 2200 ohms, I get a value of 3340 ohms on the lcd display. When I use a resistor whose colour bars indicate R2 = 10000 ohms, I get a reading of 13230 on the lcd, yet the value of Vout is correct for the known R1 and the approximate value of R2 from it’s colour bars.

From my limited knowledge of the use of voltage dividers, I used the formula for the value of R2 as
R2 = ( Vout * R1 ) / ( Vin - Vout )
but the resultant value of R2 is way off, yet the Vout value is what I would reasonably expect.

What am I doing wrong ?

 /* A sketch to measure the value of a test resistor using a voltage divider
  *  
  *  Description: A 16 x 2 LCD is set up as normal, with the exception of the contrast pin of the lcd
  *  is connected to a PWM pin 9 of the Arduino, and a fixed contrast level of 9300 maintains the lcd
  *  contrast to my liking, which negates using a potentiometer. 
  *  
  *  A Voltage Divider circuit is set up using a resistor of a known and tested value ( R1 ) and a 
  *  resistor whose value is unknown ( R2 ). The voltage division between the 2 resistors is input
  *  to analog pin A5 for reading. 
  *  
  *  The program first prints out the value of the voltage divider to 2 decimal places, and then
  *  prints the value of R2 using ohms law.
  */
 
 #include <LiquidCrystal.h>          // must include this header file
 
 const byte RS = 12, EN = 11, VO = 9, D4 = 5, D5 = 4, D6 = 3, D7 = 2;  // allocate appropriate pins
 
 LiquidCrystal lcd ( RS, EN, D4, D5, D6, D7 ); // initialise the lcd pins. Must include this.

 word setContrast;                   // holds the current contrast variable

 const word R1 = 9990;           // value of the fixed, known resistor ( in this case 9990 ohms )
 const byte Vin = 5;                // value of the input voltage to R1 ( in this case 5v )
 float sensorPin = A5  ;           // allocate pin A5 to read the voltage divider
 float Vout = 0;                      // variable to hold the value at the voltage divider, and used in the map() function
 word R2;                              // test resistor

 void setup()
 {
  const byte columns = 16;         // sets the number of columns on the lcd ( change for different lcd )
  const byte rows = 2;               // sets the number of rows --- ditto ---

  setContrast = 9300;                // this works for my lcd screens. Valid number between 9220 and 9325

  pinMode ( A5, INPUT );
  pinMode ( VO, OUTPUT );             // make the lcd's VO output enabled
  analogWrite ( VO, setContrast );   // intialise the contrast setting 
  lcd.begin ( columns, rows );         // initialise the lcd columns and rows. Must include this.
  
  
 } // end of setup()

 void loop()
 {
  Vout = ( float ) analogRead ( A5 ) *5 / 1023; // read Vout and store as floating point numbers
  lcd.clear();
  lcd.write ( "Vout = " );           
  lcd.setCursor ( 7, 1 );
  lcd.print ( Vout, 2 );             // print Vout value to 2 decimal places
  lcd.write ( " volts");
  delay ( 2000 );

  lcd.clear();
  lcd.write ( "Value R2 =" );
  lcd.setCursor ( 2, 1 );
  lcd.print ( ( Vout * R1 ) / ( Vin - Vout ) );    // calculate the value of R2
  lcd.write ( " ohms" );
  delay ( 2000 );
  
 } // end of loop

Not looked at this in any detail but what initially strikes me is the use of different variable types in the maths calculations - liable to cause problem, as a principle I use the same type of variable in any math functions to be sure the calculation is correct. You could “int” for all of the variables.

I’d look at the maths again - if you think about it Vin is “1023”, Vout is the analog read number ( e.g. 245). So you can do the math with these numbers, the 5v is not needed.
So Vin -Vout is just 1023 -245 in my examples.

Not sure why you have Vout = (float)…

You might have a mistake there as you’ve used “float” to define a sensor pin.