RaftI2C is the I2C component library for the Raft ESP32 framework.
It provides two main layers:
I2CCentral: a low-level I2C master implementation for ESP32-class devices, intended to be more robust than the standard master path for Raft bus-management use cases.BusI2C: a Raft bus implementation with automatic scanning, device detection, device identification, initialization, polling, multiplexer support, and optional per-slot power control.
RaftI2C is designed for projects that need to discover and manage I2C devices dynamically. It supports devices connected directly to the main I2C bus and devices behind PCA9548A-style multiplexers. A background worker task handles scanning and polling, while Raft's device manager exposes discovered devices and data through the normal Raft APIs.
More Raft documentation is available in the RaftCore wiki. There is also a blog post describing the auto-identification approach: I2C Auto-identification.
- components/RaftI2C: the ESP-IDF component implementation.
- TestWebUI: an ESP32 example firmware with a browser UI for viewing discovered I2C devices and live poll data.
- unit_tests: ESP-IDF unit-test project.
- linux_unit_tests: host-side tests and generated records used during development.
- scripts: helper scripts for generated device records and related tooling.
In an ESP-IDF/Raft application, include RaftI2C as a component and register the I2C bus type during startup:
#include "BusI2C.h"
raftBusSystem.registerBus("I2C", BusI2C::createFn);The bus instances themselves are created from the active systype configuration under DevMan/Buses/buslist. A minimal bus entry looks like this:
{
"name": "I2CA",
"type": "I2C",
"sdaPin": 8,
"sclPin": 9,
"i2cFreq": 100000
}More advanced configurations can add fields such as lockupDetect, mux, ioExps, pwr, and slotControl for multiplexed buses, IO expanders, per-slot power, and per-slot I2C/serial mode control.
TestWebUI is a complete Raft firmware example. It runs BusI2C, hosts a web server, and serves a React-based WebUI from the ESP32 file system. The UI is built during the firmware build, copied into the LittleFS image, flashed to the device, and then accessed from a web browser.
The WebUI source is in TestWebUI/systypes/Common/WebUI. The common features file enables the web app and LittleFS image generation:
set(FS_TYPE "littlefs")
set(FS_IMAGE_PATH "../Common/FSImage")
set(UI_SOURCE_PATH "../Common/WebUI")The build runs the WebUI build, copies the generated files into the filesystem image area, compresses assets by default, creates fs.bin, and flashes it alongside the firmware image.
The browser UI connects directly to the device using Raft RICJSON messages on the devjson WebSocket topic. It does not depend on the separate raftjs package. Generic fixed-layout poll responses are decoded from the device type metadata, while devices with packed FIFO responses need a matching custom decoder in the WebUI. The example currently includes custom FIFO decoding for MAX30101 and LSM6DS.
Install:
- ESP-IDF for the target ESP32 family.
- The Raft CLI: https://crates.io/crates/raftcli
- Node.js and npm for the WebUI build.
On WSL, make sure node and npm resolve to Linux binaries, not Windows npm.cmd. A quick check is:
which node
which npm
node --version
npm --versionFrom the example folder:
cd TestWebUI
raft build -i -s RoboticalAxiom1 -c
raft flash -s RoboticalAxiom1Common development shortcuts are:
# Build only
raft b -i -s RoboticalAxiom1
# Clean build
raft b -i -s RoboticalAxiom1 -c
# Build, flash, and monitor
raft r -i -s RoboticalAxiom1Available example systypes currently include:
RoboticalAxiom1: ESP32-S3, USB Serial/JTAG console, I2C on SDA 8 / SCL 9, plus mux, IO expander, power, and slot-control configuration.qtpys3: ESP32-S3, USB Serial/JTAG console.tinypico: ESP32, UART console.
The active systype config is merged from TestWebUI/systypes/Common and the selected systype folder. For example, RoboticalAxiom1 adds its board-specific SysTypes.json and sdkconfig.defaults on top of the common defaults.
After flashing, connect to the serial monitor and look for startup logs from RaftI2CBusI2C, SerialConsole, WebServer, and periodic system reports. The WebUI is served by the device's web server. Once the device is on the network, open the device IP address in a browser, for example:
http://192.168.1.250/
If station Wi-Fi is not configured or available, connect to the configured access point instead and browse to the device on that network.
The firmware build handles WebUI bundling automatically, but the UI can also be run locally while developing it:
cd TestWebUI/systypes/Common/WebUI
npm install
npm run startTo create the production WebUI bundle manually:
npm run buildThe production build writes to dist. During the ESP-IDF/Raft build, those files are copied into the generated LittleFS image and flashed to the device file-system partition.
Each systype can override the common firmware and WebUI settings:
features.cmake: target chip, Raft components, file-system settings, WebUI source path.sdkconfig.defaults: ESP-IDF defaults such as console transport, partition table, flash size, and target-specific options.SysTypes.json: Raft runtime configuration, including buses, devices, network services, and sysmods.
To change I2C pins, edit the selected systype's SysTypes.json under:
DevMan -> Buses -> buslist
For example:
{
"name": "I2CA",
"type": "I2C",
"sdaPin": 8,
"sclPin": 9,
"i2cFreq": 100000
}Console settings are intentionally target-specific. ESP32-S3 boards that expose USB Serial/JTAG should use CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y. ESP32 boards such as TinyPICO generally use the UART console instead.
Host-side tests can be built from linux_unit_tests:
cd linux_unit_tests
make allESP-IDF unit tests live under unit_tests and use the normal ESP-IDF/Raft build flow for the unittest systype.
If the build fails while generating the WebUI, check that Linux node and npm are installed and first on PATH. In WSL, accidentally invoking Windows npm can fail when the build path is a WSL UNC path.
If serial output appears to stop after early boot messages, check the selected systype's console setting. Early ROM/bootloader output may appear on a USB serial port even when the application console later switches to UART0. For ESP32-S3 USB Serial/JTAG monitoring, the generated sdkconfig should contain:
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
If a selected systype appears to use the wrong I2C pins, inspect the generated merged config:
cat TestWebUI/build/<systype>/raft/SysTypes.json.mergedThis file shows the actual runtime configuration compiled into the firmware.
If a device is detected but does not show live values in the WebUI, check the device type's devInfoJson.resp metadata. Simple responses are decoded automatically from the attribute list, but records with a custom resp.c.n handler, such as lsm6ds_fifo, must also be implemented in TestWebUI/systypes/Common/WebUI/src/CustomAttrHandler.ts.
