does anyone know how to read a voltage of around 15v with ads1115

Hello I have been trying to figure out how to meter a 12 volt lead acid battery of mine with this
16 bit adc ads1115 seems to be very accurate less than 5 volts i can get a resolution to less than 1mv

if i can meter a 12 volt battery close to that it would be great within 10mv would be great .. i know that the internal ref is 6.144 for this ADC divide that by 32764 and you get .0001875 which is great for less than 5 volts does anyone know how to write the code for this

here is the code to read up to vcc with 5v i was using it to charge a 100f cap to 2.5 volts worked
with my 12 volt battery and a logic mosfet

#include <math.h>
#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f,20,4);
Adafruit_ADS1115 ads(0x48);
float Voltage2 = 0.0;
float Voltage = 0.0;
int outputPin= 0;

void setup(void) 
{
 
  lcd.backlight();
  lcd.init(); // initialize the lcd 
  lcd.init();
  pinMode(8,OUTPUT); 
  pinMode(7,OUTPUT); 
  
  ads.begin();
}

void loop(void) 
{
  
  float adc0;  // we read from the ADC, we have a sixteen bit integer as a result
  //float adc1;
  adc0 = ads.readADC_SingleEnded(0);
  Voltage = (adc0 * 0.1875)/1000;

 // adc1 = ads.readADC_SingleEnded(1);
 // Voltage2 = (adc1 * 0.1875)/1000;
//float T2=Thermister(adc1);
 int T3= analogRead(A3);
  lcd.setCursor(0,1);
  lcd.print("Voltage: ");
  lcd.print(Voltage,4);  
  lcd.setCursor(0,0);
  //lcd.print("Batt_Temp ");
  //lcd.print(Thermistor(T3));
  if(Thermistor(T3)>=110.0){digitalWrite(8,LOW);digitalWrite(7,LOW);}
  else{
  if(Voltage <= 2.500){digitalWrite(8,HIGH);digitalWrite(7,LOW);}
  else{digitalWrite(8,LOW);digitalWrite(7,HIGH);}}
  delay(500);
}


//*********************************************Steinhart-Hart equation************************************************
double Thermistor(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;              // Convert Kelvin to Celsius
 Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
 return Temp;
}
//******************************************************************************************************************

bandmwhitt2013:
Hello I have been trying to figure out how to meter a 12 volt lead acid battery of mine with this
16 bit adc ads1115 seems to be very accurate less than 5 volts i can get a resolution to less than 1mv

if i can meter a 12 volt battery close to that it would be great within 10mv would be great .. i know that the internal ref is 6.144 for this ADC divide that by 32764 and you get .0001875 which is great for less than 5 volts does anyone know how to write the code for this

here is the code to read up to vcc with 5v i was using it to charge a 100f cap to 2.5 volts worked
with my 12 volt battery and a logic mosfet

#include <math.h>

#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f,20,4);
Adafruit_ADS1115 ads(0x48);
float Voltage2 = 0.0;
float Voltage = 0.0;
int outputPin= 0;

void setup(void)
{

lcd.backlight();
 lcd.init(); // initialize the lcd
 lcd.init();
 pinMode(8,OUTPUT);
 pinMode(7,OUTPUT);
 
 ads.begin();
}

void loop(void)
{
 
 float adc0;  // we read from the ADC, we have a sixteen bit integer as a result
 //float adc1;
 adc0 = ads.readADC_SingleEnded(0);
 Voltage = (adc0 * 0.1875)/1000;

// adc1 = ads.readADC_SingleEnded(1);
// Voltage2 = (adc1 * 0.1875)/1000;
//float T2=Thermister(adc1);
int T3= analogRead(A3);
 lcd.setCursor(0,1);
 lcd.print("Voltage: ");
 lcd.print(Voltage,4);  
 lcd.setCursor(0,0);
 //lcd.print("Batt_Temp ");
 //lcd.print(Thermistor(T3));
 if(Thermistor(T3)>=110.0){digitalWrite(8,LOW);digitalWrite(7,LOW);}
 else{
 if(Voltage <= 2.500){digitalWrite(8,HIGH);digitalWrite(7,LOW);}
 else{digitalWrite(8,LOW);digitalWrite(7,HIGH);}}
 delay(500);
}

//Steinhart-Hart equation***
double Thermistor(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
double Temp;
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
Temp = Temp - 273.15;              // Convert Kelvin to Celsius
Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
return Temp;
}
//******************************************************************************************************************

That ADC has an input limit of 0v to Vdd (5v+0.3v) or 5.5v which ever is less. the spec sheet says +-6.144 WHICH is a LIE. the +-6.144 is the maximum digital value return by the ADC converter, the electronic voltage is limited to 0 to Vdd +0.3V. Vdd must be less than 5.5v. So, 6.144 is NEVER achievable!

If you want to read a voltage outside of this range you will have to use a resistor divider network to scale you measured voltage withing this range. If you are measuring a 6cel lead acid battery I would recommend you calculate the max scale over 15V. Sixteen or Eighteen is better. So if Vdd is 5.0v and eighteen is the max value then you need two resistor with a 5:13 ratio. Since the input impedance is 10Mohm at 6.144v full scale you should scale the resistor divider to provide one hundred time mores power than the ADC devours. This recommendation is based on experience. This recommendation limits the resistor network to 100k ohms max. A 20k bottom resistor and a 52k upper is 72k, close enough.

Now, standard 1% resistor value are 20k and 52.3k. The values match to 99.43% of perfect.

Using these values for the resistor network, the maximum resolute of the ADC becomes 678uV. This exceeds your request sensitivity by 20x.

Attached is a spread sheet PDF of the calculations

Chuck.

ADC calc.pdf (20.4 KB)

ok i have some precision 100k and 10k pots to scale down to 5v not a problem but how would i do the calculations ?

Hi,
Use this calculator.

Tom.. :slight_smile:

Correct me if I'm wrong, but if you want to use the full resolution of the A/D, you have to set the PGA to 1x.
That gives full scale at 4.096volt.

A 20k:52.3k divider will have overflow (with PGA=1x) at 4.096volt * (20k + 52.3k) / 20k = 14.8volt.

Maybe wise to use a 1:3 resistor ratio (4*4.096= 16.384volt max).
Leo..

that would be fine i just don't know how to code that with the ads1115 i have no problem doing this with arduino adc but this is truly a different creature

Wawa:
Correct me if I'm wrong, but if you want to use the full resolution of the A/D, you have to set the PGA to 1x.
That gives full scale at 4.096volt.

A 20k:52.3k divider will have overflow (with PGA=1x) at 4.096volt * (20k + 52.3k) / 20k = 14.8volt.

Maybe wise to use a 1:3 resistor ratio (4*4.096= 16.384volt max).
Leo..

I selected the 6.144 full scale resolution, which as a 0.0001875V resolution.

If instead, the 4.096V full scale resolution is selected, then, yes my resistor combination will not be able to read 18V. Your calculations are correct.

The OP quoted the 6.144V full scale resolution, so I used it.

Chuck.

this is starting to sink in.. I will have to study that

i will use that calculator TomGeorge i saved it to my book marks

bandmwhitt2013:
that would be fine i just don't know how to code that with the ads1115 i have no problem doing this with arduino adc but this is truly a different creature

If your code can correctly measure voltages from 0 to Vdd (5v), then just add the resistor divider network between the ADC and the voltage.

Here is a schematic with some explanation:

Chuck.

ok but how would i write the program to print the correct voltage

You have to calibrate, because of the voltage divider resistors/pot anyway.
So change this

Voltage = (adc0 * 0.1875)/1000;

to something like this

Voltage = adc0 * 0.0007296; // calibrate by changing the multiplication factor

Leo..

Hi,
Give us some code that reads the AtoD into a variable and we will go from there.
Just that, no extra bells a whistles, develop the code in stages.

Tom... :slight_smile:

ok Im trying to read up to 15 volts dc ...the conversion code is written.. like Wawa said i think i need to change the division factor " Voltage = adc0 * 0.0007296; // calibrate by changing the multiplication factor " you guys are trying to help me and thank you for that ...
so do you think dividing 15 by 32764 and putting the result in a variable would work ?

Displayed voltage depends on several factors.

The voltage divider lowers things by the divider ratio (resistors are not accurate).
That ratio has to be compensated for (multiplied by the same ratio) in the maths line.

The A/D produces a lower output value if you don't change the PGA gain (is the gain exactly 2/3?).

The A/D changes that voltage into an A/D value that depends on the factory calibration of it's Aref voltage.

In the end it might be best to just calculate a fixed divider that uses the full A/D range at max batt voltage.
And calibrate the end result with a good DMM.
Leo..

Hi there,

I would like to revive this older thread. I would like to read voltages of a lead/acid battery using ADS1115, but with a 3.3V Pro Mini. Am I correct in putting the following values to the calculator posted above?

Table 2 of the ADS1115 datasheet says differential input impedance for 2.048V (@PGA 2) is 4.9M. These are my inputs & outputs of the calculator.

Enter V1:
16.384 Volts

Enter V2:
2.048 Volts

Enter Total Resistance (R1 + R2):
4.9 Megohms

R1 =
4.288M Ohms

R2 =
612.5k Ohms

Preferred R1 =
4.3M Ohms

Preferred R2 =
620k Ohms

Does this make sense?

Thanks!