Platform-independent C99 driver for the TI INA228 — an 85 V, 20-bit power/energy/charge monitor with an I2C interface. (DATASHEET)
Portability comes from using a generic void *ctx pointer, which represents the platform-specific context used to access the I²C peripheral. The driver never interprets ctx directly—it simply passes it to the platform-specific I²C read/write functions.
Typical contexts:
- STM32:
I2C_HandleTypeDef * - Linux: an I2C file descriptor (usually wrapped in a small struct)
- ESP-IDF:
i2c_master_bus_handle_t
| Path | Contents |
|---|---|
inc/ |
Public header (ina228.h) |
src/ |
Driver implementation (ina228.c) |
tests/ |
Host-side unit tests (mock I2C bus) |
examples/ |
Platform port examples |
- CMake ≥ 3.15
- A C99 compiler (GCC/Clang/MSVC)
cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failureOn Windows with MSYS2/MinGW, pass a generator: -G "MinGW Makefiles".
Run the test binary directly (add .exe on Windows):
./build/test_ina228Remove compiled objects but keep the CMake cache with
cmake --build build --target clean; delete build/ entirely for a clean
rebuild.
Copy the ina228_driver folder into your project, then in your top-level
CMakeLists.txt:
add_subdirectory(ina228_driver)
target_link_libraries(your_target PRIVATE ina228)Add src/ina228.c to your source list and inc/ to your include paths.
- Implement
ina228_i2c_read_fn,ina228_i2c_write_fn, andina228_delay_ms_fnfor your platform. - Fill in an
ina228_tdescriptor (callbacks,ctx,dev_addr,shunt_resistor,max_current). - Call
ina228_init(), then read measurements.
#include "ina228.h"
ina228_t dev = { /* callbacks, ctx, dev_addr, shunt_resistor, max_current */ };
ina228_init(&dev);
float voltage, current, power;
ina228_read_voltage(&dev, &voltage);
ina228_read_current(&dev, ¤t);
ina228_read_power(&dev, &power);See inc/ina228.h for the full API.
NOTE: The public header is wrapped in extern "C", so it can be included directly
from C++ sources.