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,
|
||||
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 };
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue