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);
}
}
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 depends on how often you need the reading. If there is a long time (for some value of long ) 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.
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.
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
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?
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
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.