Reading battery voltage in project

Found this schematic and code below for reading voltage from a 7.4v LiPo and cannot get my head around exactly what is happening with the mapping. The input to the A7 is the centre tap of a 10K with a 1K to ground.
From what I can gather, the voltage into the A7 pin will be around 0.75V which I believe should give an Ad_In of around 153 given 5v as the reference. The V_Cal value is set to 1166 and again, as far as I can make out, that should give a value of approx. 174. What I cannot understand how this ends up at 760 for Ad_Cnv or 7.6v on the display.

void do_battvolts()
{
   Ad_In= analogRead(7);                                         //show battery voltage
   Ad_Cnv = map(Ad_In, 0, 1023, 0, V_Cal);          //convert to actual voltage reading
   display.setCursor(50,56);
   display.setTextSize(1);
   display.print("Batt V = ");
   display.print(Ad_Cnv/100,2);                               //show two decimal result
   display.setTextSize(2);  
}   

To clarify, you are trying to understand how the voltage divider drops your voltage from 7.4 to 0.74?

When the 7.4 volt fully charged LiPo has delivered power for some time the voltage drops. When it drops below 7 volts I'm not sure the controller feels happy.

To clarify, how does this, which I believe gives a number of approx. 174, give an output of the battery voltage here.......

Never mind the detail on battery levels falling etc. as that is not a problem as it stands.

The voltage divider gives 0.75v at the A7 input. When mapped to (assuming 5v regulated) a number between 0-1023 of 153.
This is then mapped to a calculated value between 0 and 1166 but how does this come about. As I see it it should be either 1166 as the 0.75v represents near to full battery voltage which doesn't make sense or there is some other calculation/conversion I am missing. Answer should be somewhere around 760 mark for the "print" of (Ad_Cnv/100,2) to show approx 7.66v on the display.
Note that actual precise voltage levels not important at this instance as I can recalibrate and also the battery voltage ranges from 7.4v nominal to 8.4v fully charged.

The answer is in the code that you didn't post.
See if Aref is set to INTERNAL (~1.1volt) in setup().
Leo..

That would be it......... never seen that used before, live and learn.
1st line in setup.
Makes sense now...cheers.

/*
    This is a program to use the MCP3424 A/D converter along with a Nano and OLED
    to provide a microOhmmeter function.
    This unit automatically conducts four ranges on the A/D converter and selects the proper one.
    Start date is 04/18/2019
    Complete date 04/20/2019
    Upgraded to PCB layout, complete rework of sketch program file
    Upgraded date is 07/01/2020
    Upgraded to measure test current with 0.1 Ohm resistor
    Upgraded date is 07/03/2020
    Upgraded to read over 2 OHms 08/25/2020
    Minor tweeks and a warning note
    ref Gainx1, max input voltage is 2.5 VDC for full scale ***
    ref Gainx8, max input voltage is 0.25 VDC for full scale **
 ** ref SRxxB is bit resolution, ranging from 12 to 18 bits  ***
 ** MCP 3421 has one channel input
 ** MCP 3422 has two channel inputs
 ** MCP 3424 has four channel inputs, from CH1 to Ch4
 * *************************************************************************
    WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
    DO NOT DO RESISTOR TESTS WITH ONLY THE USB POWER TO THE METER!!
    THAT RESISTOR UNDER TEST REVERSES BIASES THE ARDUINO NANO 5 VOLT REGULATOR
    AND WILL BLOW THE REGULATOR.  A 6.6 VOLT POWER SUPPLY MUST BE CONNECTED
    TO THE METER ANY TIME THE USB PC PORT IS PLUGGED INTO THE ARDUINO NANO
    WHEN CONNECTING A TEST RESISTOR TO THE MICRO OHM METER.
 *  ***********************************************************************************
*/
#include <Wire.h>
#include <MCP3424.h>
#define OLED_RESET 4
#include <Adafruit_SH1106.h>
Adafruit_SH1106 display(OLED_RESET);
MCP3424 adc(PIN_FLOAT, PIN_FLOAT);
const int V_Cal = 1000;                      //1166 number is used to calibrate voltage
float R_Cal = 1.005; //  R_CAL is the calibration of the meter against a known resistor
#if (SH1106_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SH1106.h!");
#endif
float value;  //define variable
double R5_Ohm ;
float Vx_Ohm;
float Rx_Ohm;
double range1;
double range2;
double range3;
double range4;
float test_resistor;
float Ad_Cnv = 0;
int Ad_In = 0;
void setup()
{
  analogReference(INTERNAL);
  Serial.begin(9600);
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);// initialize 128/64 with the I2C addr 0x3D

  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.clearDisplay();

  display.setCursor(25, 0);
  display.print("uOhm");

  display.setCursor(20, 30);
  display.print("meter");
  display.display();
  delay(1000);
}
void do_R5ohm()              //measure the voltage on 5 Ohm 1% resistor for calculation
{
  adc.creg[CH4].bits = {GAINx8, R16B, CONTINUOUS, CH4, 1 };
  ConvStatus err = adc.read(CH4, R5_Ohm);                           //Read 5 Ohm Volts
  R5_Ohm  = R5_Ohm * 10.14;         //R5_Ohm variable contains voltage drop on resistor
}
void do_range1()               //following routines runs variable settings on channel 3
{
  adc.creg[CH3].bits = {GAINx8, R18B, CONTINUOUS, CH3, 1 };
  ConvStatus err1 = adc.read(CH3, range1);                             //Read Rx Volts
  range1 = range1 * R_Cal / R5_Ohm;
}
void do_range2()
{
  adc.creg[CH3].bits = {GAINx1, R18B, CONTINUOUS, CH3, 1 };
  ConvStatus err2 = adc.read(CH3, range2); //Read Rx Volts             //Read Rx Volts
  range2 = range2 * R_Cal / R5_Ohm;
}
void do_range3()
{
  adc.creg[CH3].bits = {GAINx2, R14B, CONTINUOUS, CH3, 1 };
  ConvStatus err1 = adc.read(CH3, range3);                             //Read Rx Volts
  range3 = range3 * R_Cal / R5_Ohm;
}
void do_range4()
{
  adc.creg[CH3].bits = {GAINx1, R12B, CONTINUOUS, CH3, 1 };
  ConvStatus err1 = adc.read(CH3, range4);                             //Read Rx Volts
  range4 = range4 * R_Cal / R5_Ohm;
}
void do_battvolts()
{
  Ad_In = analogRead(7);                                        //show battery voltage
  Ad_Cnv = map(Ad_In, 0, 1024, 0, V_Cal);          //convert to actual voltage reading
  display.setCursor(50, 56);
  display.setTextSize(1);
  display.print("Batt V = ");
  display.print(Ad_Cnv / 100, 2);                            //show two decimal result
  display.setTextSize(2);

}
//*************************************************************************************
//main program starts here
void loop()
{
  display.setTextSize(2);
  display.setTextColor(WHITE);
  do_R5ohm();                                        //run voltage on 5 ohm resistor

  Serial.println  (R5_Ohm, 5);
  if (R5_Ohm < 0.01)           //if A/D result is negative, no test resistor is connected
  {
    display.clearDisplay();
    display.setCursor(0, 20);
    display.setTextSize(4);
    display.print("OPEN!");
    display.display();
  }
  else                                          //do the entire resistance check program
  {
    do_range1();
    do_range2();
    do_range3();
    do_range4();
    // Serial.print ("R5 ");
    // Serial.println (R5_Ohm, DEC);               //send to USB for test_resistor purposes
    test_resistor =  max(range1, range2);        //identify the maximum resistance value
    test_resistor =  max(test_resistor, range3);
    test_resistor =  max(test_resistor, range4);
    if (test_resistor > 2.0)                             //if over 2 ohms, show over range
    {
      display.clearDisplay();                                                //over range
      display.setCursor(0, 0);
      display.print("Over");
      display.setCursor(0, 25);
      display.print("Range");
      display.display();
    }
    else
    {
      //  Serial.print ("  test_resistor=");
      //  Serial.println  (test_resistor, DEC);
      display.clearDisplay();
      display.setCursor(80, 38);
      display.print("Ohm");                                              //show ohms value
      display.setCursor(0, 38);
      display.print(test_resistor, 4);

      display.setCursor(80, 19);
      display.print("mOhm");
      display.setCursor(0, 19);
      display.display();
      //  Serial.println  (test_resistor, DEC);
      if (test_resistor * 1000 > 999)    //show milliohms result for either xxxx.xx, or xxxx
      {
        display.print(test_resistor * 1000, 0);                       //show milliohms value
        display.display();
      }
      else
      {
        display.print(test_resistor * 1000, 2);
        display.display();
      }
      if (test_resistor * 1000000 < 999999)             //test for maximum uOhm digit display
      {
        display.setCursor(80, 0);                              //if under 999999, display it
        display.print("uOhm");
        display.setCursor(0, 0);
        display.print(test_resistor * 1000000, 0);
        do_battvolts();
        display.display();
      }
      else
      {
        display.setCursor(0, 0);
        display.print("      ");
        display.display();
      }
    }
  }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.