ADS1115 - Open input channel issue - Solved #4

I am using a ESP32 + ADS1115 to measure three parameters and post to Blynk. ( IoT project )

Channel 0 : Temperature from a LM35
Channel 1 : Li-Ion Battery Voltage scaled down by 50% - so mostly around 2V
Channel 2&3: Current with CT in differential mode.

Working OK but not accurately. But what I notice is even without connecting LM35, I read about 28 Deg C. I measure the A0 Pin of ADS1115 and of course it reads Zero. Also generally the LM35 readings are about 2 deg more than actual.

So I am sure this is due to some bug in the code - the way I am reading the channels. I am producing the full code applicable for teh ADC section and would like if there is any obvious mistake I am doing . ( Swapped the ADS1115 another new one and same result )

Thanks for any help..

#include "RunningAverage.h"
#include <Adafruit_ADS1015.h>

// Remove all libraries for WiFi and Blynk to keep this code compact..

//##################################

// User Config parameters

int raSampleSize = 25;
double battMinVolt = 3;                    // For scaling battery percent
double battMaxVolt = 4.2;
byte flashLED  = 4;                        // On board LED
float adsSpan = 4.096 ;                    // Full span of the ADC for the chosen gain..
float factor = 30;                         // 30A = 1V
float multiplier  = 0.0635  ;              // 1 bit = 0.0625mV but using 0.0635 to adjust the reported current

//#################################

bool ledState;
int16_t adc0, adc1 ;
long adcDegC, adcBatt;
float degC ;
float BVolt ;
int battPercent;

Adafruit_ADS1115 ads;                            // Instantiate the ADS

RunningAverage ra_adc0(raSampleSize);            // Temp Sensor ...
RunningAverage ra_adc1(raSampleSize);            // Li Ion Batt volts * 0.5


//########## S E T U P ############

void setup()
{
  Serial.begin(9600);
  pinMode( flashLED, OUTPUT);
  digitalWrite(flashLED, LOW);
  delay(2000);
  Serial.println("LM35 & CurrSensor Read and Post to Blynk.");
  ads.setGain(GAIN_TWO);                   // 2x gain   +/- 2.048V  1 bit  0.0625mV
  ads.begin();
  
  postToBlynkServer();                    // Removed all setup code for the Blynk server to keep code Compact for Forum

}

//########### L O O P #############

void loop()                                // Use this for continuous posting ...  #NSM - Uncomment all code inside in Loop
{
  
}

//#################################

void postToBlynkServer ()                         // Use this for sleep mode #NSM
{
  // Post channel values to Cloud. Max limit is 10Values per second
  digitalWrite(flashLED, HIGH);
  getDegC_BattV();                                 // Read the Degc and Batt values
  digitalWrite(flashLED, LOW);
  float Amps = getAmpere();                        // Read the Ampere value
//  Blynk.virtualWrite(ambientTemp, degC);
//  Blynk.virtualWrite(acAmpere, Amps);
//  Blynk.virtualWrite(batteryLevel, battPercent);
  Serial.print( " Posted to Blynk : " );
  Serial.print(Amps);
  Serial.print(" , ");
  Serial.print(degC);
  Serial.print(" , ");
  Serial.println(battPercent);
}

//*********************************

void getDegC_BattV()
{
  ra_adc0.clear();
  ra_adc1.clear();
  for (byte count = 0; count < 25; count++)
  {
    adc0 = ads.readADC_SingleEnded(0);
    adc1 = ads.readADC_SingleEnded(1);
    ra_adc0.addValue(adc0);
    ra_adc1.addValue(adc1);
    adcDegC = ra_adc0.getAverage();
    adcBatt = ra_adc1.getAverage();
    delay(5);
  }
  degC = float(adcDegC * adsSpan * 100 / 65535) ;

  BVolt = float(2 * adcBatt * adsSpan / 65535);    // 2 To account for 50:50 Potential divider
  battPercent = ((BVolt - battMinVolt) / (battMaxVolt - battMinVolt)) * 100;
}

//*********************************

float getAmpere()                 // Read the current sensor SCT013 in differential mode
{
  float voltage;
  float ampere ;
  float sum = 0;
  long startMillis = millis();
  int counter = 0;

  while ( millis() - startMillis < 1000 )
  {
    voltage = ads.readADC_Differential_2_3() * multiplier ;
    ampere  = voltage * factor ;
    ampere /= 1000.0;
    sum += sq(ampere);
    counter = counter + 1;
    delay(5);
  }
  ampere = sqrt(sum / counter);

  return (ampere);
}

You failed to post a wiring diagram of your setup.

So I am sure this is due to some bug in the code

Why do you know that the hardware is wired correctly?

pylon:
You failed to post a wiring diagram of your setup.

Why do you know that the hardware is wired correctly?

I know .. but it may take a while before I can sketch /scan and post the circuit !

Anyway being Wemos D32 board all is on a single board and the only other module is the ADS1115. And beyond the power supply it links to the MCU via SCK and SDA. Rest four pins connect to sensors and I have measured them to be OK ... the LM35 when connected reads the room temperature as 0.286 V and 0.0 when disconnected. So is the case with the Current sensor and Battery level .

I was only wondering if its due to ADC input stage settling time issue... normally when adjacent channels measure voltages which differ too much, then I guess some additional precautions need be taken.

Are you supplying the LM35 with 5V? What does it read with your DMM?

After getting the responses I had to rethink on the hardware part... as software seemed to be ok ( else someone would have pointed out )

So its back to basics - floating Analog Inputs. A 100K resistor between the A0 and GND solved the problem.

The penalty for forgetting basics is two days of searching for non-existent problems !!