Thanks for the tip @majrooo . I have been playing around w/the Axp class, and I'm closer, but not fully there. From your reply (and the PowerWake example), it sounds like GetVapsData() is supposed to return the overall capacity, and GetVbatData() is supposed to return the current voltage, but that's not whatI'm seeing though. Here is a sample:
#include <M5StickC.h>
RTC_TimeTypeDef RTC_TimeStruct;
void displayInfo(void);
void setCursorToLine(int lineNumber);
void setup()
{
M5.begin();
M5.Axp.begin();
RTC_TimeTypeDef timeStruct;
timeStruct.Hours = 0;
timeStruct.Minutes = 0;
timeStruct.Seconds = 0;
M5.Rtc.SetTime(&timeStruct);
M5.Lcd.setRotation(1);
}
void loop()
{
M5.Lcd.fillScreen(BLACK);
displayInfo();
delay(1000);
}
void displayInfo(void)
{
uint16_t vbatData = M5.Axp.GetVbatData(); // docs: "Get the battery voltage value"
double vbat = vbatData * 1.1 / 1000;
setCursorToLine(1);
M5.Lcd.printf("vbat: %.3f V ", vbat);
// charging: 4.188 V
// unplugged: 4.068 V (fully charged)
// unplugged: 3.068 V (45 minutes later, about to turn off)
uint16_t vapsData = M5.Axp.GetVapsData(); // docs: "Get battery capacity"
double vaps = vapsData * 1.4 / 1000;
setCursorToLine(2);
M5.Lcd.printf("vaps: %.3f V ", vaps);
// charging: 4.971 V
// unplugged: 4.068 V (fully charged)
// unplugged: 3.066 V (45 minutes later, about to turn off)
double batteryLevel = 100.0 * ((vaps - 3.0) / (vbat - 3.0));
setCursorToLine(3);
M5.Lcd.printf("batteryLevel: %.1f%% ", batteryLevel);
M5.Rtc.GetTime(&RTC_TimeStruct);
setCursorToLine(4);
M5.Lcd.printf("%02d:%02d:%02d", RTC_TimeStruct.Hours, RTC_TimeStruct.Minutes, RTC_TimeStruct.Seconds);
}
void setCursorToLine(int lineNumber)
{
const int X_LOCATION = 5;
const int Y_LOCATION = 0;
const int LINE_HEIGHT = 20;
M5.Lcd.setCursor(X_LOCATION, Y_LOCATION + ((lineNumber - 1) * LINE_HEIGHT), 2);
}
When charging, I'm getting:
uint16_t vbatData = M5.Axp.GetVbatData(); // docs: "Get the battery voltage value"
double vbat = vbatData * 1.1 / 1000;
// charging: 4.188 V
uint16_t vapsData = M5.Axp.GetVapsData(); // docs: "Get battery capacity"
double vaps = vapsData * 1.4 / 1000;
// charging: 4.971 V
After fully charge and then disconnected, I get:
uint16_t vbatData = M5.Axp.GetVbatData(); // docs: "Get the battery voltage value"
double vbat = vbatData * 1.1 / 1000;
// unplugged: 4.068 V (fully charged)
uint16_t vapsData = M5.Axp.GetVapsData(); // docs: "Get battery capacity"
double vaps = vapsData * 1.4 / 1000;
// unplugged: 4.068 V (fully charged)
..and later on, when the battery is around 3V and just about to power off, I had:
uint16_t vbatData = M5.Axp.GetVbatData(); // docs: "Get the battery voltage value"
double vbat = vbatData * 1.1 / 1000;
// unplugged: 3.068 V (45 minutes later, about to turn off)
uint16_t vapsData = M5.Axp.GetVapsData(); // docs: "Get battery capacity"
double vaps = vapsData * 1.4 / 1000;
// unplugged: 3.066 V (45 minutes later, about to turn off)
I was expecting the value from GetVapsData() to remain constant, but as you can see, vbat tracked almost 1:1 with vaps.
So I then hard-coded the "max battery capacity" value to 4.07 and changed batteryLevel to:
//double batteryLevel = 100.0 * ((vaps - 3.0) / (vbat - 3.0));
double batteryLevel = 100.0 * ((vaps - 3.0) / (4.07 - 3.0));
setCursorToLine(3);
M5.Lcd.printf("batteryLevel: %.1f%% ", batteryLevel);
...and this works, but I don't like having to hard-code the max-battery-capacity value to 4.07 and would rather there was a way to programmatically get this value.
I feel like there must be a way to do this, but I'm not seeing how with the methods in Axp.
If I were to refactor my current code for batteryLevel into a function, it would be:
double getBatteryLevel(void)
{
uint16_t vbatData = M5.Axp.GetVbatData();
double vbat = vbatData * 1.1 / 1000;
uint16_t vapsData = M5.Axp.GetVapsData();
double vaps = vapsData * 1.4 / 1000;
return 100.0 * ((vaps - 3.0) / (4.07 - 3.0));
}
What would be a better implementation for getBatteryLevel()?
Thanks,
Jeff