Skip to content

Commit

Permalink
Feature/max1704x (#135)
Browse files Browse the repository at this point in the history
* feat(max1704x): added max1704x component and example

* updated doc comment

* doc: update

* ci: update

* doc: rebuild

* doc: rebuild

* fix: bad index into buffer

* feat(max1704x): update charge rate
* Updated charge rate to use int16_t instead of uint16_t to get proper negative values for charge rate
* Updated example to support qtpy ESP32 PICO, QtPy ESP32s3, and custom hardware via menuconfig

* readme: update

* doc: rebuild
  • Loading branch information
finger563 authored Jan 9, 2024
1 parent aa3e909 commit 2fd32ac
Show file tree
Hide file tree
Showing 110 changed files with 2,802 additions and 312 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ jobs:
target: esp32
- path: 'components/math/example'
target: esp32
- path: 'components/max1704x/example'
target: esp32
- path: 'components/monitor/example'
target: esp32
- path: 'components/mcp23x17/example'
Expand Down
4 changes: 4 additions & 0 deletions components/max1704x/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
REQUIRES "logger" "math"
)
21 changes: 21 additions & 0 deletions components/max1704x/example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# add the component directories that we want to use
set(EXTRA_COMPONENT_DIRS
"../../../components/"
)

set(
COMPONENTS
"main esptool_py i2c task max1704x"
CACHE STRING
"List of components to include"
)

project(max1704x_example)

set(CMAKE_CXX_STANDARD 20)
34 changes: 34 additions & 0 deletions components/max1704x/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# MAX1704X Example

This example shows how to use the MAX1704X driver to control

## How to use example

### Hardware Required

This example requires a connection (via I2C) to a dev board which has a MAX1704X
battery gauge chip. The example was tested with a QtPy ESP32s3 dev board and a
MAX1704X breakout board from Adafruit, but can be configured (using
`menuconfig`) to run on any ESP board by configuring the I2C pins and selecting
`CUSTOM` hardware.

- [MAX17048 Breakout board from Adafruit](https://www.adafruit.com/product/5580)
- [QtPy ESP32 Pico](https://www.adafruit.com/product/5395)

### Build and Flash

Build the project and flash it to the board, then run monitor tool to view serial output:

```
idf.py -p PORT flash monitor
```

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type ``Ctrl-]``.)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

## Example Output

![CleanShot 2024-01-09 at 08 24 25](https://github.com/esp-cpp/espp/assets/213467/13699053-ba1d-4af3-a5e0-dbcbd772b2d7)
2 changes: 2 additions & 0 deletions components/max1704x/example/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS ".")
39 changes: 39 additions & 0 deletions components/max1704x/example/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
menu "Example Configuration"

choice EXAMPLE_HARDWARE
prompt "Hardware"
default EXAMPLE_HARDWARE_QTPYPICO
help
Select the hardware to run this example on.

config EXAMPLE_HARDWARE_QTPYPICO
depends on IDF_TARGET_ESP32
bool "Qt Py PICO"

config EXAMPLE_HARDWARE_QTPYS3
depends on IDF_TARGET_ESP32S3
bool "Qt Py S3"

config EXAMPLE_HARDWARE_CUSTOM
bool "Custom"
endchoice

config EXAMPLE_I2C_SCL_GPIO
int "SCL GPIO Num"
range 0 50
default 19 if EXAMPLE_HARDWARE_QTPYPICO
default 40 if EXAMPLE_HARDWARE_QTPYS3
default 19 if EXAMPLE_HARDWARE_CUSTOM
help
GPIO number for I2C Master clock line.

config EXAMPLE_I2C_SDA_GPIO
int "SDA GPIO Num"
range 0 50
default 22 if EXAMPLE_HARDWARE_QTPYPICO
default 41 if EXAMPLE_HARDWARE_QTPYS3
default 22 if EXAMPLE_HARDWARE_CUSTOM
help
GPIO number for I2C Master data line.

endmenu
71 changes: 71 additions & 0 deletions components/max1704x/example/main/max1704x_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <chrono>
#include <vector>

#include "i2c.hpp"
#include "logger.hpp"
#include "max1704x.hpp"
#include "task.hpp"

using namespace std::chrono_literals;

extern "C" void app_main(void) {

//! [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({.name = "Max1704x Task",
.callback = task_fn,
.stack_size_bytes = 5 * 1024,
.log_level = espp::Logger::Verbosity::WARN});
fmt::print("%time(s), voltage (V), SoC (%), Charge Rate (%/hr)\n");
task.start();
//! [max1704x example]
while (true) {
std::this_thread::sleep_for(100ms);
}
}
11 changes: 11 additions & 0 deletions components/max1704x/example/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CONFIG_FREERTOS_HZ=1000

# ESP32-specific
#
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240

# Common ESP-related
#
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
Loading

0 comments on commit 2fd32ac

Please sign in to comment.