Using ADS1115 instead of Arduino Nano built in ADC

I have made a battery coulomb counting meter (Coulometer) for my ebike. I was using Arduino nano for it. I am using the built in adc of nano to read the output of ACS712-30A current sensing module. in overall measurement, I charge to 100% till charger cutsoff and then discharge to 40% and then recharge again till charger cutsoff I get 15 to 20% error. the adc of nano has a error of +/- 2 LSB which is +/- 9.8mV. The output of AC712-30A is 66mV/Amp. 9.8 mV is around 15% of 66mV.
To reduce the error I wish to use the ADS1115 16 bit adc module. I am unable to understand whether I should run it in SingleShot or continuous mode. Please guide. I have only posted a part of the code because the complete code is very big and maybe confusing. If required I can post the complete code

void setup() {
  
  Serial.begin(9600);
  lcd.begin(20,4);
  lcd.clear();

  startMillis = millis();  //initial start time
  start_ms = millis();
}

void loop() {
  
  currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  if ((currentMillis - startMillis) >= period){  //test whether the period (200mSec) has elapsed
    startMillis = currentMillis;                 //IMPORTANT to save the start time.
    power_calc();                                // Run Voltage, Current and Wattage Calculations
} 
	
void power_calc(){

  unsigned long int wt = 0;
  float volts = 00.00;
  float current = 00.00;
  unsigned char Samples = 100;

  
  for (int i=0; i < Samples; i++){
    // Battery Voltage
    vadc = analogRead(A0);                                                         // Read A0 for voltage
    volts += (float)(vadc * 4.89);
  }
  if(vadc < 500) {
    save_data();
  }
  
  unsigned long StartCalc = millis();
  
  // Start of Code to be modified
  /******************************/
  for (int i=0; i < 3; i++){ // Stabilize the ADC
    a = analogRead(A3);
    delay(1);
  }
  // Battery Current. read output of ACS712
  for (int i=0; i < Samples; i++){
    a = analogRead(A3);                                                       // Read A3 for current
    // ACS712-30A=6.6,20A=10
    if (a >= 511){                                                            // Battery Discharging
      current = (float)(current + (((a - 512) * 4.89) / 6.6)); //4.8828      
    }
    else if (a < 510){                                                       // Battery Charging
      current = (float)(current + (((512 - a) * 4.89) / 6.6));
    }
  }
  // End of Code to be modified
  /****************************/
  
  unsigned long EndCalc = millis() - StartCalc;
  Serial.print("ADCs read Time: "); Serial.println(EndCalc); // Time taken 20 ms
  if (a >= 511){
    sign = '-';                                                             // Battery Discharging
    charging_flag = 0;                                                      // show that battery is discharging
  }
  else if (a < 510){
    sign = '+';                                                             // Battery Charging
    charging_flag = 1;                                                      // show that battery is Charging
  }
  volts = (float)(volts / Samples);
  fltVolts += (float)volts;
  current = (float) (current / Samples);
  fltCurrent += (float)current;
  mAsec = (float)(current / 180);                                             // mA/0.2Sec ( mA/200ms)
    
  if(DspUpdInt > 4){                                                         // Display Voltage,Current,Watts every 1 Second
    //////////////////////
    //***LCD Line 1 ***//
    /// Voltage Display ///
    volts = (unsigned int)(fltVolts / 5) ;                                   // Voltage to display
    display_va(0, 0, volts);
    amps = (unsigned int)((fltCurrent / 5) * 10);
    if(amps >= 1000){
      lcd.setCursor(7, 0);
      lcd.print(sign);
    }
    display_va(8, 0, amps);  
    /// Display Wattage  ///
    wt = ((long)volts * amps) / 10000;
      display_perc_watts(16, 0, wt);
  }
}

There is a library available for it.
IDE -> Include Library -> Manage Libraries
Search for ADS1115

I know that

ADC error = +/-2 / 1024 = +/- 0.2%
ACS712 full scale error = +/-3.5mV / (30*66mv) = +/-0.18%

I would say you are doing something wrong.

I did not know that the adc error was calculated on full scale. I thought it was per reading like if the calculated adc value is 500 than it could show between 498 to 502.
Please correct me if I am wrong.
Also the in use practical reading error is 15 to 20% which is why I want to connect an external ADC.

It's the usually way of specifying errors for measuring devices.

I thought it was per reading like if the calculated adc value is 500 than it could show between 498 to 502.

It could or it could only show exactly 500. It depends on the DNL of the ADC.

Also the in use practical reading error is 15 to 20% which is why I want to connect an external ADC.

If that is true, then you either have a hardware error, a software error or probably both.

It depends on how often you need the reading. If there is a long time (for some value of long :slightly_smiling_face:) between readings then single shot mode will allow power saving between readings.

Power saving in adc is in micro amps or very low mili amps which doesn't really matter. I have a 18aH battery. While using the Arduino Nano ADC I was taking 50 reading then averaging it to reduce noise. This would complete in about 20ms.

You will still have 15-20% error but now with a higher resolution.

I have a 18aH battery.
I am using the built in adc of nano to read the output of ACS712-30A current sensing module.

What current/voltage is charging the battery?

The ACS712-30A does not sound like a good match. If total current is less than 10A, then it might be better to use the INA 250 shunt resistor/amplifier package which has more precision. I have also seen discussions of reliability issues with the ACS712's.

https://www.ti.com/lit/ds/symlink/ina250.pdf?ts=1721224714037&ref_url=https%253A%252F%252Fwww.google.com%252F

The max drain current from the battery is about 18 amps usually starting from stop or climbing steeps. I mostly within 3 amps drain current. The charging voltage is 42v at 2amps. Lifepo4 battery 12S3P battery

If I have a higher resolutions then I have higher accuracy so lower percentage of error.

Very little of the overall error can be attributed to the ADC quantization error. You will not see any perciptable change in accuracy when going from 10 bit to 16 bit. Actually, it could get worse if the total ADC errors for the 16 bit are more than the 10 bit. You would be bettor off examining your code and present circuit for errors. See post #4

Averaging is a lousy way to deal with noisy readings. A single wildly wrong reading can easily skew the average by a lot. By far the BEST approach is to figure out where the noise is coming from, and deal with it before the ADC sees it. The next best approach is to filter, rather than averaging. If the problem is occassional erroneous readings, a median filter can very effectively eliminate the noisy readings. Follow that with a low-pass filter, and you will get a MUCH better result than simple averaging.

Bad idea.
Combining a ratiometric sensor with an absolute A/D introduces another error.
Supply voltage variations of the ACS712 now also enters into the mix, which was previously compensated by the ratiometric A/D of the Nano (assuming classic Nano).
Leo..

I have changed the bandwidth capacitor on the acs712 from 10nF to 1uF to limit the bandwidth thus reducing high frequency noise. The acs712 is wired to the Arduino Nano using a sheilded cable and the Arduino with the display is enclosed in a metal box with the body connnected to negative terminal. The power supply is drawing supply from the battery so it's pure dc

Isn't it possible to get a simple answer like Using the ADS1115 will not make a difference but if you are ready to try, here is the code, this is how you incorporate it in your code.
Was it my mistake to provide the reason why I want to use the external ADC?
Should I have just asked how to incorporate the ads1115 in my code?

Let us operate the ADC of Arduino NANO using internal 1.1V for the VREF of the ADC.

Full Scale       : 1.1V (1100 mV)
LSB Weight       : 1.1/1023 = 1.08 mV
Permissible Error: +/- 2 LSB = 2.16 mV

//---------------------------------------------------------

AC712's output: 66 mV/amp
%Error: (2.16/66.0)/100 = 3.3% per amp (close to acceptance level of +/- 2%)

For a 5 volt supply The ACS712-30A gives 2.5V for 0 current and 66mv/Amp +/- 2.5V depending on the direction of the current flowing through the input pins. So the reference for the Arduino would be supply voltage = 5V. By the formula

Full Scale      : 5.0V (5000mV)
LSB Weight      : 5.0/1023 = 4.88 mV
Permisible Error: +/- 2 LSB = 9.76 mV

ACS712-30A output : 66 mV/amp
Error  : (9.76/66.0)/100 = 14.78%

Thats the error I am already getting

Characterization data of ADS1115 shows the following: 
Offset at 25 deg C is around - 3 LSB for 5V supply,
 but can be up to -6 LSB. Gain error ranges from around 0.02 to 0.06%, 
which is below the gain error given as the maximum of 0.15%.
Even if I round up the 0.15% to 1% for ADS1115 than the 14.78% 
error of the ADC of the Arduino Nano is too High

that's because people is trying to help based in experience, beyond what you see now

that can't be correct, otherwise the ADC would be completely useless. The error of the Arduino ADC is below 1%.

If you see that level of deviation there should be a problem somewhere else. And another ADC will not change that.

You will improve from:

  • 14% unknown error + 1% of ADC
    to
  • 14% of still unknown error + 0.1% of the new ADC.

The same for the other device. First is to find the reason of the huge deviation, in hardware, software, or both.
That's why people is asking for more details.