ADS1115 + ESP32 - Monitoring Negative and Positive voltages

Hi everybody,

Im trying to use an ADS1115 + ESP32 to measure 2 x 15 volt batteries wired in series. Id like to monitor the voltage on both batteries at the same time.

-15VDC - 0 - +15VDC

So I have a simple voltage divider (resistors) to measure one of the batteries 0 - +15VDC and supply the ADS1115 A0 input from 0VDC - 6VDC

As the max negative voltage of the ADS1115 is -300mv , do I need another voltage divider to change the -15VDC - 0V , to -300mv - 0V?

Or is there another way?

Here is my code

#include "ADS1X15.h"
#include <SPI.h>
#include <TFT_eSPI.h>
#include <Wire.h>

ADS1115 ADS(0x48);
TFT_eSPI tft = TFT_eSPI();

void setup() 
{
  Serial.begin(115200);
  Serial.println(__FILE__);
  Serial.print("ADS1X15_LIB_VERSION: ");
  Serial.println(ADS1X15_LIB_VERSION);

  ADS.begin();

    tft.init();

   tft.setRotation(1);
}

void loop() 
{
  //ADS.setGain(0);


  int16_t val_0 = ADS.readADC(0);  



  float f = ADS.toVoltage(1) * 6.988;  // voltage factor

  Serial.print("Analog0: "); Serial.print(val_0); Serial.print('\t'); Serial.print(val_0 * f, 3);


  Serial.println();
  tft.fillScreen(TFT_BLACK);
 tft.setCursor(2, 47, 2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.println("H");
  tft.setCursor(15, 5, 8);
  tft.print(val_0 * f, 3);
  
  delay(1000);
}

To be able to measure below zero, you can use resistors to lift the voltage higher so it can be measured. You need a known positive voltage. If the 3.3V is 3.300V, then you can use that. Does the ADS1115 have some kind of internal reference ?

Could you use three dots or something else for the "up to", because I get confused.
This I understand: negative 15 up to zero is -15 ... 0

[ADDED]
It turns out that it can measure below zero: https://www.best-microcontroller-projects.com/ads1115.html But the datasheet indicates otherwise, depending on the mode that is used.
Perhaps you could use a single voltage divider or two analog inputs with both a voltage divider. I don't have a ADS1115 to test it with negative voltages.

1 Like

Many thanks!

You got me thinking, ill use 2 voltage dividers, and reference 0V to the ADS at the -15V end of the battery series, thus giving me 2 posivite voltages for the ADS1115 A0 and A1

:pray::+1:

Could you draw a schematic ? Just with a pen on a piece of paper is okay.

There is no absolute zero voltage, like there is an absolute zero in temperature. What is considered zero volts is often a completely free choice for the circuit designer, unless the choice is determined by some larger circuit designed by someone else.

So why not choose zero volts to be the negative terminal of the first battery? Then, the positive terminal of the other battery is 30V and the point between the two batteries is 15V. Then you have no negative voltages to deal with.

1 Like

Yea...i thought that was a great idea for a while too...however the 0-30v measurement will not be accurate as its not 1 battery being measured, its a combination of 2.

Anyway, thanks for your helpπŸ‘

How to measure the voltage on each battery with one ads1115?

The ads1115 says there is a differential mode, maybe i should try that?

Why would it be inaccurate?

Because it assumes the discharge rate for both batteries ,to be exactly the same

What do you want to do with that 2*15volt battery, and how is it related to ground of the Arduino.
Is it to make 30volt, or a bipolar 15volt supply.

The ADS can measure negative voltages, if you connect 'ground' of your voltage divider to a known voltage, like 3.3volt. And also measure that bias voltage with the third input of the ADS.
We need to know your full setup to give you the right advice.
Leo..

Hi Leo, the 2 x 15V batteries in series , to make for a 30V supply. I 'd like to monitor the voltage of both batteries while keeping them in series.

I have an ADS and ESP32 .

-15V - 3.3V = -11.7V .... is max negative is -300mV?

If... you ground the 30volt battery (-) to ADS/Arduino ground,
then just use two voltage dividers to 2volt (for max resolution on a 3.3volt supply).
One from the full 30volt, and another one from the 15volt tap.
Power the ADS with the 3.3volt supply of the ESP32, and set PGA to 2 (2.048volt).

Only if you use a bipolar supply (center of the two batteries grounded), then you should think of the more complex way of biasing one voltage divider. Biasing divider ground with a positive supply keeps the divider output always positive.
Leo..

1 Like

Thanks Leo, your 1st suggestion should work if the batteries discharge at exactly the same rate.

I would have taken a different tact.

Measure the voltage from ground to the + of the bottom cell. Measure from ground to top of both batteries.

Subtract the bottom voltage from the top voltage, that would be the voltage across the top battery.

No fooling around with negative voltage, that's a can of worms..

Good luck

:smiley_cat:

1 Like

Many thanks!

Will give this a go

:+1:

Exactly what I was trying to say.
Leo..

1 Like

Thanks guys :slight_smile:

The idea was that you measure the voltage at the point between the batteries as well as the total voltage. You were always going to measure the voltage at two points versus 0V, my suggestion was just to change what you define as 0V and measure the voltage at the two other points.

OK if I were to do this and only needed two of the four channels the ADS 1115 has I would just use two channels configured as differential. The ADS 1115 has programmable gain which looks like this.

void setup(void) 
{
  Serial.begin(9600);
 
  
  // ads.setGain(GAIN_TWOTHIRDS);  +/- 6.144V  1 bit = 0.1875mV (default)
  // ads.setGain(GAIN_ONE);        +/- 4.096V  1 bit = 0.125mV
  // ads.setGain(GAIN_TWO);        +/- 2.048V  1 bit = 0.0625mV
  // ads.setGain(GAIN_FOUR);       +/- 1.024V  1 bit = 0.03125mV
  // ads.setGain(GAIN_EIGHT);      +/- 0.512V  1 bit = 0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    +/- 0.256V  1 bit = 0.0078125mV 
  ads. Begin();
}

This assumes a 5.0 volt supply. Less setting a gain it I "think" defaults to +/- 6.144V 1 bit = 0.1875mV (default). Just remove the // for the gain you want. Now before I go any further with this it can be argued based on the data sheet that it won't measure negative voltages. It works just fine for me.

Here is an example of my code:

#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <LiquidCrystal_I2C.h>
 
Adafruit_ADS1115 ads(0x48);
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

int16_t rawADCvalue1;  // The is where we store the value we receive from the ADS1115
int16_t rawADCvalue2;
float scalefactor = 0.1875F; // This is the scale factor for the default +/- 6.144 Volt Range we will use
float volts1 = 0.0; // The result of applying the scale factor to the raw value
float volts2 = 0.0; 

void setup(void)
{
  Serial.begin(9600);
  ads.begin();
   // Initialize LCD screen
  lcd.init();                      // initialize the lcd 
  lcd.init();
  lcd.backlight();
}
 
void loop(void)
{
 rawADCvalue1 = ads.readADC_Differential_0_1(); 
 rawADCvalue2 = ads.readADC_Differential_2_3();
 volts1 = (rawADCvalue1 * scalefactor)/1000.0;
 volts2 = (rawADCvalue2 * scalefactor)/1000.0;
 
//Serial Print Data
  Serial.print("Channel 1 =  "); 
  Serial.println((volts1),3);
  Serial.print ("");
  Serial.println (" Volts");
  Serial.print("Channel 2 =  "); 
  Serial.println((volts2),3);
  Serial.println (" Volts");
  Serial.println();

 // LCD Data
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Channel 1 = ");
  lcd.print(( volts1),3); // Using 3:1 Voltage Divider so volts1 * 3
  lcd.print(" V");
  lcd.setCursor(0,1);
  lcd.print("Channel 2 = ");
  lcd.print((volts2),3);
  lcd.print(" V");
  lcd.setCursor(0,2);  
 
delay(2000);

You can modify it to suit your needs and of course figure in your divider circuit and do the math. I have used this code on an Arduino UNO as well as an ESP8266. You can eliminate all the code for the display I used. Set up your ADS 1115 for the address you choose. I powered the ADS with 5.0 volts. The SCL and SDA to pins D1 and D2 of my WAP board. 

On the differential inputs of the ADS1115 A0 is + and A1 is - A2 is + and A3 is -. So connect across your batteries accordingly. Never tried it with batteries and dividers but it should work.

Ron