MAX1704X
The MAX17048/MAX17049 ICs are tiny, micropower current fuel gauges for lithium-ion (Li+) batteries in handheld and portable equipment. The MAX17048 operates with a single lithium cell and the MAX17049 with two lithium cells in series.
The ICs use the sophisticated Li+ battery-modeling algorithm ModelGauge™ to track the battery relative state-of-charge (SOC) continuously over widely varying charge and discharge conditions. The ModelGauge algorithm eliminates current-sense resistor and battery-learn cycles required in traditional fuel gauges. Temperature compensation is implemented using the system microcontroller.
The ICs automatically detect when the battery enters a low-current state and enters low-power 3µA hibernate mode, while still providing accurate fuel gauging. The ICs automatically exit hibernate mode when the system returns to active state.
On battery insertion, the ICs debounce initial voltage measurements to improve the initial SOC estimate, thus allowing them to be located on system side. SOC, voltage, and rate information is accessed using the I2C interface. The ICs are available in a tiny 0.9mm x 1.7mm, 8-bump wafer-level package (WLP), or a 2mm x 2mm, 8-pin TDFN package.
API Reference
Header File
Classes
-
class Max1704x : public espp::BasePeripheral<>
Class to interface with the MAX1704x battery fuel gauge.
This class is used to interface with the MAX1704x battery fuel gauge. It is used to get the battery voltage, state of charge, and charge/discharge rate.
See also
https://cdn-learn.adafruit.com/assets/assets/000/114/607/original/MAX17048-MAX17049.pdf?1661966692
MAX1704X Example
espp::Logger logger({.tag = "Max1704x example", .level = espp::Logger::Verbosity::INFO}); // make the I2C that we'll use to communicate logger.info("initializing i2c driver..."); espp::I2c i2c({ .port = I2C_NUM_0, .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO, .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO, }); // now make the max1704x which handles GPIO espp::Max1704x max1704x({.write = std::bind(&espp::I2c::write, &i2c, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), .read = std::bind(&espp::I2c::read, &i2c, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), .log_level = espp::Logger::Verbosity::WARN}); std::error_code ec; // and finally, make the task to periodically poll the max1704x and print // the state. NOTE: the Max1704x does not internally manage its own state // update, so whatever rate we use here is the rate at which the state will // update. auto task_fn = [&](std::mutex &m, std::condition_variable &cv) { // NOTE: sleeping in this way allows the sleep to exit early when the // task is being stopped / destroyed { std::unique_lock<std::mutex> lk(m); cv.wait_for(lk, 50ms); } static auto start = std::chrono::high_resolution_clock::now(); auto now = std::chrono::high_resolution_clock::now(); auto seconds = std::chrono::duration<float>(now - start).count(); std::error_code ec; auto voltage = max1704x.get_battery_voltage(ec); if (ec) { return false; } auto soc = max1704x.get_battery_percentage(ec); if (ec) { return false; } auto charge_rate = max1704x.get_battery_charge_rate(ec); if (ec) { return false; } fmt::print("{:0.2f}, {:0.2f}, {:0.2f}, {:0.2f}\n", seconds, voltage, soc, charge_rate); // don't want to stop the task return false; }; auto task = espp::Task({.callback = task_fn, .task_config = { .name = "Max1704x Task", .stack_size_bytes = 5 * 1024, }, .log_level = espp::Logger::Verbosity::WARN}); fmt::print("%time(s), voltage (V), SoC (%), Charge Rate (%/hr)\n"); task.start();
Public Types
-
typedef std::function<bool(uint8_t)> probe_fn
Function to probe the peripheral
- Param address
The address to probe
- Return
True if the peripheral is found at the given address
Public Functions
-
inline explicit Max1704x(const Config &config)
Construct a new Max1704x object.
- Parameters
config – Configuration for the MAX1704x.
-
inline void initalize(std::error_code &ec)
Initialize the MAX1704x.
-
inline uint16_t get_version(std::error_code &ec)
Get the IC version.
- Parameters
ec – Error code set if an error occurs.
- Returns
The IC version.
-
inline uint8_t get_chip_id(std::error_code &ec)
Get the Chip ID.
- Parameters
ec – Error code set if an error occurs.
- Returns
The chip ID.
-
inline float get_battery_voltage(std::error_code &ec)
Get the battery voltage.
- Parameters
ec – Error code set if an error occurs.
- Returns
The battery voltage in V.
-
inline float get_battery_percentage(std::error_code &ec)
Get the battery state of charge.
This is the percentage of battery charge remaining.
- Parameters
ec – Error code set if an error occurs.
- Returns
The battery state of charge in %.
-
inline float get_battery_charge_rate(std::error_code &ec)
Get the battery charge or discharge rate.
This is the rate at which the battery is charging or discharging. A positive value indicates charging. A negative value indicates discharging. Units are in % per hour.
- Parameters
ec – Error code set if an error occurs.
- Returns
The battery charge or discharge rate in %/hr.
-
inline AlertStatus get_alert_status(std::error_code &ec)
Get the alert status.
This is the current alert status of the battery.
- Parameters
ec – Error code set if an error occurs.
- Returns
The battery alert status as an AlertStatus.
-
inline void clear_alert_status(uint8_t flags_to_clear, std::error_code &ec)
Clear the alert status.
This clears the alert status of the battery.
- Parameters
flags_to_clear – The flags to clear.
ec – Error code set if an error occurs.
- inline bool probe (std::error_code &ec) requires(UseAddress)
Probe the peripheral
Note
This function is thread safe
Note
If the probe function is not set, this function will return false and set the error code to operation_not_supported
Note
This function is only available if UseAddress is true
- Parameters
ec – The error code to set if there is an error
- Returns
True if the peripheral is found
- inline void set_address (uint8_t address) requires(UseAddress)
Set the address of the peripheral
Note
This function is thread safe
Note
This function is only available if UseAddress is true
- Parameters
address – The address of the peripheral
- inline void set_probe (const probe_fn &probe) requires(UseAddress)
Set the probe function
Note
This function is thread safe
Note
This should rarely be used, as the probe function is usually set in the constructor. If you need to change the probe function, consider using the set_config function instead.
Note
This function is only available if UseAddress is true
- Parameters
probe – The probe function
-
inline void set_write(const write_fn &write)
Set the write function
Note
This function is thread safe
Note
This should rarely be used, as the write function is usually set in the constructor. If you need to change the write function, consider using the set_config function instead.
- Parameters
write – The write function
-
inline void set_read(const read_fn &read)
Set the read function
Note
This function is thread safe
Note
This should rarely be used, as the read function is usually set in the constructor. If you need to change the read function, consider using the set_config function instead.
- Parameters
read – The read function
-
inline void set_read_register(const read_register_fn &read_register)
Set the read register function
Note
This function is thread safe
Note
This should rarely be used, as the read register function is usually set in the constructor. If you need to change the read register function, consider using the set_config function instead.
- Parameters
read_register – The read register function
-
inline void set_write_then_read(const write_then_read_fn &write_then_read)
Set the write then read function
Note
This function is thread safe
Note
This should rarely be used, as the write then read function is usually set in the constructor. If you need to change the write then
- Parameters
write_then_read – The write then read function
-
inline void set_separate_write_then_read_delay(const std::chrono::milliseconds &delay)
Set the delay between the write and read operations in write_then_read
Note
This function is thread safe
Note
This should rarely be used, as the delay is usually set in the constructor. If you need to change the delay, consider using the set_config function instead.
Note
This delay is only used if the write_then_read function is not set to a custom function and the write and read functions are separate functions.
- Parameters
delay – The delay between the write and read operations in write_then_read
-
inline void set_config(const Config &config)
Set the configuration for the peripheral
Note
This function is thread safe
Note
The configuration should normally be set in the constructor, but this function can be used to change the configuration after the peripheral has been created - for instance if the peripheral could be found on different communications buses.
- Parameters
config – The configuration for the peripheral
-
inline void set_config(Config &&config)
Set the configuration for the peripheral
Note
This function is thread safe
Note
The configuration should normally be set in the constructor, but this function can be used to change the configuration after the peripheral has been created - for instance if the peripheral could be found on different communications buses.
- Parameters
config – The configuration for the peripheral
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters
rate_limit – The rate limit to use for the logger
Public Static Attributes
-
static constexpr uint8_t DEFAULT_ADDRESS = 0x36
Default address of the MAX1704x.
-
struct Config
Configuration for the MAX1704x.
-
typedef std::function<bool(uint8_t)> probe_fn