cogito/esphome_dev/esphome/components/max17043/max17043.cpp

98 lines
3.1 KiB
C++

#include "max17043.h"
#include "esphome/core/log.h"
namespace esphome {
namespace max17043 {
// MAX174043 is a 1-Cell Fuel Gauge with ModelGauge and Low-Battery Alert
// Consult the datasheet at https://www.analog.com/en/products/max17043.html
static const char *const TAG = "max17043";
static const uint8_t MAX17043_VCELL = 0x02;
static const uint8_t MAX17043_SOC = 0x04;
static const uint8_t MAX17043_CONFIG = 0x0c;
static const uint16_t MAX17043_CONFIG_POWER_UP_DEFAULT = 0x971C;
static const uint16_t MAX17043_CONFIG_SAFE_MASK = 0xFF1F; // mask out sleep bit (7), unused bit (6) and alert bit (4)
static const uint16_t MAX17043_CONFIG_SLEEP_MASK = 0x0080;
void MAX17043Component::update() {
uint16_t raw_voltage, raw_percent;
if (this->voltage_sensor_ != nullptr) {
if (!this->read_byte_16(MAX17043_VCELL, &raw_voltage)) {
this->status_set_warning("Unable to read MAX17043_VCELL");
} else {
float voltage = (1.25 * (float) (raw_voltage >> 4)) / 1000.0;
this->voltage_sensor_->publish_state(voltage);
this->status_clear_warning();
}
}
if (this->battery_remaining_sensor_ != nullptr) {
if (!this->read_byte_16(MAX17043_SOC, &raw_percent)) {
this->status_set_warning("Unable to read MAX17043_SOC");
} else {
float percent = (float) ((raw_percent >> 8) + 0.003906f * (raw_percent & 0x00ff));
this->battery_remaining_sensor_->publish_state(percent);
this->status_clear_warning();
}
}
}
void MAX17043Component::setup() {
ESP_LOGCONFIG(TAG, "Running setup");
uint16_t config_reg;
if (this->write(&MAX17043_CONFIG, 1) != i2c::ERROR_OK) {
this->status_set_warning();
return;
}
if (this->read(reinterpret_cast<uint8_t *>(&config_reg), 2) != i2c::ERROR_OK) {
this->status_set_warning();
return;
}
config_reg = i2c::i2ctohs(config_reg) & MAX17043_CONFIG_SAFE_MASK;
ESP_LOGV(TAG, "MAX17043 CONFIG register reads 0x%X", config_reg);
if (config_reg != MAX17043_CONFIG_POWER_UP_DEFAULT) {
ESP_LOGE(TAG, "Device does not appear to be a MAX17043");
this->status_set_error("unrecognised");
this->mark_failed();
return;
}
// need to write back to config register to reset the sleep bit
if (!this->write_byte_16(MAX17043_CONFIG, MAX17043_CONFIG_POWER_UP_DEFAULT)) {
this->status_set_error("sleep reset failed");
this->mark_failed();
return;
}
}
void MAX17043Component::dump_config() {
ESP_LOGCONFIG(TAG, "MAX17043:");
LOG_I2C_DEVICE(this);
if (this->is_failed()) {
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
}
LOG_UPDATE_INTERVAL(this);
LOG_SENSOR(" ", "Battery Voltage", this->voltage_sensor_);
LOG_SENSOR(" ", "Battery Level", this->battery_remaining_sensor_);
}
float MAX17043Component::get_setup_priority() const { return setup_priority::DATA; }
void MAX17043Component::sleep_mode() {
if (!this->is_failed()) {
if (!this->write_byte_16(MAX17043_CONFIG, MAX17043_CONFIG_POWER_UP_DEFAULT | MAX17043_CONFIG_SLEEP_MASK)) {
ESP_LOGW(TAG, "Unable to write the sleep bit to config register");
this->status_set_warning();
}
}
}
} // namespace max17043
} // namespace esphome