Am I reading this incorrectly or is there truly something wrong with my battery monitor. I am using the MAX17048 to monitor the voltage and SOC of a 3.7V 2500mAh li-ion battery and I am running the example sketch provided by the library and I am currently reading:
3.473 V
0.64 % SOC
That doesn't make sense to me since in their comments in the source file says SOC is reported from 0 - 100.0 %.
I have VIN, GND, SDA, and SCL connected only.
#include <Streaming.h>
#include "Adafruit_MAX1704X.h"
Adafruit_MAX17048 maxlipo;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // wait until serial monitor opens
Serial.println(F("\nAdafruit MAX17048 simple demo"));
while (!maxlipo.begin()) {
Serial.println(F("Couldnt find Adafruit MAX17048?\nMake sure a battery is plugged in!"));
delay(2000);
}
Serial.print(F("Found MAX17048"));
Serial.print(F(" with Chip ID: 0x"));
Serial.println(maxlipo.getChipID(), HEX);
}
void loop() {
float cellVoltage = maxlipo.cellVoltage();
if (isnan(cellVoltage)) {
Serial.println("Failed to read cell voltage, check battery is connected!");
delay(2000);
return;
}
Serial.print(F("Batt Voltage: ")); Serial.print(cellVoltage, 3); Serial.println(" V");
Serial.print(F("Batt Percent: ")); Serial.print(maxlipo.cellPercent(), 2); Serial.println(" %");
Serial.println();
delay(2000); // dont query too often!
}
Could You present a pen and paper drawing of the setup?
As soon as a fully charged battery delivers current the voltage will decrease. How much varies.
Does the manual tell about calibration?
You could make a test measuring on a charged battery that is not connected to any load. The see what value You get.
There are various functions in the source code that talks about resetting and auto-calibration.
RESET
/*!
* @brief Soft reset the MAX1704x
* @return True on reset success
*/
bool Adafruit_MAX17048::reset(void) {
Adafruit_BusIO_Register cmd =
Adafruit_BusIO_Register(i2c_dev, MAX1704X_CMD_REG, 2, MSBFIRST);
// send reset command, the MAX1704 will reset before ACKing,
// so I2C xfer is expected to *fail* with a NACK
if (cmd.write(0x5400)) {
return false;
}
// loop and attempt to clear alert until success
for (uint8_t retries = 0; retries < 3; retries++) {
if (clearAlertFlag(MAX1704X_ALERTFLAG_RESET_INDICATOR)) {
return true;
}
}
// something didn't work :(
return false;
}
AUTO-CALIBRATE
/*!
* @brief Quick starting allows an instant 'auto-calibration' of the
battery. However, its a bad idea to do this right when the battery is first
plugged in or if there's a lot of load on the battery so uncomment only if
you're sure you want to 'reset' the chips charge calculator.
*/
void Adafruit_MAX17048::quickStart(void) {
Adafruit_BusIO_Register mode_reg =
Adafruit_BusIO_Register(i2c_dev, MAX1704X_MODE_REG);
Adafruit_BusIO_RegisterBits quick_bit =
Adafruit_BusIO_RegisterBits(&mode_reg, 1, 6);
quick_bit.write(true);
// bit is cleared immediately
}
It seems to me that the problem is in the library, in this function below: It predicts that the ADC value is 10 bits. (return percent / 256.0;), it returns the value divided by 256. But if the "Arduino" is 12 bits, then the calculation will be wrong.
The SOC register is a read-only register that displays
the state of charge of the cell as calculated by the
ModelGauge algorithm. The result is displayed as a
percentage of the cell’s full capacity. This register
automatically adapts to variation in battery size since
the MAX17043/MAX17044 naturally recognize relative
SOC. Units of % can be directly determined by observing only the high byte of the SOC register. The low byte
provides additional resolution in units 1/256%. The
reported SOC also includes residual capacity, which
might not be available to the actual application because
of early termination voltage requirements. When SOC()
= 0, typical applications have no remaining capacity.
The first update occurs 125ms after POR of the IC.
Subsequent updates occur at variable intervals
depending on application conditions. ModelGauge calculations outside the register are clamped at minimum
and maximum register limits. Figure 4 shows the SOC
register format.
What is the tolerance of the parts you’re using? Also, what is the calibration status of your meter, and is it currently in calibration? The difference you’re observing seems to be a result of a stack-up of tolerances.