Don't reset the MAX17043 battery fuel gauge after waking from Deep Sleep (#19412)

* fix: don't reset the device when coming out of deep sleep

* fix: move debug log message to inside the device validation

* Update xsns_110_max17043.ino

* add: update global battery percentage when max17043 reports new value
This commit is contained in:
Paul Blacknell 2023-09-09 08:48:30 +01:00 committed by GitHub
parent 7726f1eef4
commit 4cc81f0dbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 14 deletions

View File

@ -515,10 +515,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_MAX };
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_SENSOR, SRC_MAX };
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
"Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47";
"Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47|Sensor";
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };

View File

@ -1,7 +1,8 @@
/*
xsns_110_max17043.ino - Support for MAX17043 fuel-gauge systems Lipo batteries for Tasmota
Copyright (C) 2023 Vincent de Groot
Copyright (c) 2023 Vincent de Groot
Copyright (c) 2023 Paul Blacknell
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -40,6 +41,8 @@
#define XSNS_110 110
#define XI2C_83 83 // See I2CDEVICES.md
#define MAX17043_NAME "MAX17043"
#define MAX17043_ADDRESS 0x36
#define MAX17043_VCELL 0x02
#define MAX17043_SOC 0x04
@ -48,39 +51,74 @@
#define MAX17043_CONFIG 0x0c
#define MAX17043_COMMAND 0xfe
#define MAX17043_MODE_COMMAND_POWERONRESET 0x5400
#define MAX17043_MODE_COMMAND_QUICKSTART 0x4000
#define MAX17043_CONFIG_POWER_UP_DEFAULT 0x971c
#define MAX17043_CONFIG_NO_COMPENSATION 0x9700
bool max17043 = false;
int battery_latest = 101;
/*********************************************************************************************/
void Max17043Init(void) {
if (I2cSetDevice(MAX17043_ADDRESS)) {
I2cWrite16(MAX17043_ADDRESS, MAX17043_COMMAND, 0x5400); // Power on reset
if (REASON_DEEP_SLEEP_AWAKE == ESP_ResetInfoReason()) {
// if waking from deep sleep we assume the hardware design maintained power to the MAX17043
// retaining its model of the internal dynamics the battery
// if the hardware design doesn't (to conserve battery) then we lose some of
// the benefits of the device anyway as it'll be re-learning from scratch every DeepSleepTime seconds.
// to confirm this is a MAX17043 - check for both the default (if the MAX17043 did lose it's power)
// or our setting if power was maintained
if (I2cRead16(MAX17043_ADDRESS, MAX17043_CONFIG) == MAX17043_CONFIG_NO_COMPENSATION
|| I2cRead16(MAX17043_ADDRESS, MAX17043_CONFIG) == MAX17043_CONFIG_POWER_UP_DEFAULT) {
max17043 = true;
I2cSetActiveFound(MAX17043_ADDRESS, MAX17043_NAME);
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SNS: Waking from deep sleep - skipping " MAX17043_NAME " Power on Reset & Quick Start"));
}
} else {
// otherwise perform a full Power on Reset (which is the same as disconnecting power)
// and a Quick Start which essentially does the same but handles a noisy power up sequence
I2cWrite16(MAX17043_ADDRESS, MAX17043_COMMAND, MAX17043_MODE_COMMAND_POWERONRESET);
delay(10);
if (I2cRead16(MAX17043_ADDRESS, MAX17043_CONFIG) == 0x971c) { // Default 0x971c
I2cWrite16(MAX17043_ADDRESS, MAX17043_MODE, 0x4000); // Quick start
I2cWrite16(MAX17043_ADDRESS, MAX17043_CONFIG, 0x9700);
if (I2cRead16(MAX17043_ADDRESS, MAX17043_CONFIG) == MAX17043_CONFIG_POWER_UP_DEFAULT) { // Read the default to confirm this is a MAX17043
I2cWrite16(MAX17043_ADDRESS, MAX17043_MODE, MAX17043_MODE_COMMAND_QUICKSTART);
I2cWrite16(MAX17043_ADDRESS, MAX17043_CONFIG, MAX17043_CONFIG_NO_COMPENSATION);
delay(10);
max17043 = true;
I2cSetActiveFound(MAX17043_ADDRESS, "MAX17043");
I2cSetActiveFound(MAX17043_ADDRESS, MAX17043_NAME);
}
}
}
}
void Max17043Show(bool json) {
float voltage = (1.25f * (float)(I2cRead16(MAX17043_ADDRESS, MAX17043_VCELL) >> 4)) / 1000.0; // Battery voltage in Volt
uint16_t per = I2cRead16(MAX17043_ADDRESS, MAX17043_SOC);
float percentage = (float)((per >> 8) + 0.003906f * (per & 0x00ff)); // Battery remaining charge in percent
int battery_current;
// During charging the percentage might be (slightly) above 100%. To avoid strange numbers
// in the statistics the percentage provided by this driver will not go above 100%
if (percentage > 100.0) { percentage = 100.0; }
// only update the system percentage if it's changed
battery_current = int(round(percentage));
if (battery_latest != battery_current) {
char cmnd[30];
sprintf(cmnd, "%s %d", D_CMND_ZIGBEE_BATTPERCENT, battery_current);
ExecuteCommand(cmnd, SRC_SENSOR);
battery_latest = battery_current;
}
if (json) {
ResponseAppend_P(PSTR(",\"MAX17043\":{\"" D_JSON_VOLTAGE "\":%3_f,\"" D_JSON_BATTPERCENT "\":%2_f}"), &voltage, &percentage );
ResponseAppend_P(PSTR(",\"" MAX17043_NAME "\":{\"" D_JSON_VOLTAGE "\":%3_f,\"" D_JSON_BATTPERCENT "\":%2_f}"), &voltage, &percentage );
#ifdef USE_WEBSERVER
} else {
// WSContentSend_Voltage("MAX17043", voltage);
WSContentSend_PD(PSTR("{s}MAX17043 " D_VOLTAGE "{m}%1_f" D_UNIT_VOLT "{e}"), &voltage);
WSContentSend_PD(PSTR("{s}MAX17043 " D_BATTERY_CHARGE "{m}%1_f %% {e}"), &percentage);
WSContentSend_PD(PSTR("{s}" MAX17043_NAME " " D_VOLTAGE "{m}%1_f" D_UNIT_VOLT "{e}"), &voltage);
WSContentSend_PD(PSTR("{s}" MAX17043_NAME " " D_BATTERY_CHARGE "{m}%1_f " D_UNIT_PERCENT " {e}"), &percentage);
#endif
}
}