mirror of https://github.com/arendst/Tasmota.git
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:
parent
7726f1eef4
commit
4cc81f0dbc
|
@ -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,
|
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_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|"
|
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|"
|
"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 };
|
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
/*
|
/*
|
||||||
xsns_110_max17043.ino - Support for MAX17043 fuel-gauge systems Lipo batteries for Tasmota
|
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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -40,6 +41,8 @@
|
||||||
#define XSNS_110 110
|
#define XSNS_110 110
|
||||||
#define XI2C_83 83 // See I2CDEVICES.md
|
#define XI2C_83 83 // See I2CDEVICES.md
|
||||||
|
|
||||||
|
#define MAX17043_NAME "MAX17043"
|
||||||
|
|
||||||
#define MAX17043_ADDRESS 0x36
|
#define MAX17043_ADDRESS 0x36
|
||||||
#define MAX17043_VCELL 0x02
|
#define MAX17043_VCELL 0x02
|
||||||
#define MAX17043_SOC 0x04
|
#define MAX17043_SOC 0x04
|
||||||
|
@ -48,39 +51,74 @@
|
||||||
#define MAX17043_CONFIG 0x0c
|
#define MAX17043_CONFIG 0x0c
|
||||||
#define MAX17043_COMMAND 0xfe
|
#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;
|
bool max17043 = false;
|
||||||
|
int battery_latest = 101;
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
void Max17043Init(void) {
|
void Max17043Init(void) {
|
||||||
if (I2cSetDevice(MAX17043_ADDRESS)) {
|
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);
|
delay(10);
|
||||||
if (I2cRead16(MAX17043_ADDRESS, MAX17043_CONFIG) == 0x971c) { // Default 0x971c
|
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, 0x4000); // Quick start
|
I2cWrite16(MAX17043_ADDRESS, MAX17043_MODE, MAX17043_MODE_COMMAND_QUICKSTART);
|
||||||
I2cWrite16(MAX17043_ADDRESS, MAX17043_CONFIG, 0x9700);
|
I2cWrite16(MAX17043_ADDRESS, MAX17043_CONFIG, MAX17043_CONFIG_NO_COMPENSATION);
|
||||||
delay(10);
|
delay(10);
|
||||||
max17043 = true;
|
max17043 = true;
|
||||||
I2cSetActiveFound(MAX17043_ADDRESS, "MAX17043");
|
I2cSetActiveFound(MAX17043_ADDRESS, MAX17043_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Max17043Show(bool json) {
|
void Max17043Show(bool json) {
|
||||||
float voltage = (1.25f * (float)(I2cRead16(MAX17043_ADDRESS, MAX17043_VCELL) >> 4)) / 1000.0; // Battery voltage in Volt
|
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);
|
uint16_t per = I2cRead16(MAX17043_ADDRESS, MAX17043_SOC);
|
||||||
float percentage = (float)((per >> 8) + 0.003906f * (per & 0x00ff)); // Battery remaining charge in percent
|
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
|
// 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%
|
// in the statistics the percentage provided by this driver will not go above 100%
|
||||||
if (percentage > 100.0) { percentage = 100.0; }
|
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) {
|
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
|
#ifdef USE_WEBSERVER
|
||||||
} else {
|
} else {
|
||||||
// WSContentSend_Voltage("MAX17043", voltage);
|
WSContentSend_PD(PSTR("{s}" MAX17043_NAME " " D_VOLTAGE "{m}%1_f" D_UNIT_VOLT "{e}"), &voltage);
|
||||||
WSContentSend_PD(PSTR("{s}MAX17043 " 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);
|
||||||
WSContentSend_PD(PSTR("{s}MAX17043 " D_BATTERY_CHARGE "{m}%1_f %% {e}"), &percentage);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue