Skip to content
Rob Dobson edited this page Feb 21, 2026 · 1 revision

I2C Bus

Overview

Raft's I2C bus support is provided by the RaftI2C library. When a bus of type "I2C" is declared in the DevMan configuration, Raft creates a BusI2C instance that manages the complete lifecycle of I2C devices on that bus:

  • Automatic device detection through priority-based scanning, including devices behind bus multiplexers
  • Device type identification using WHO_AM_I registers and configurable detection sequences
  • Device initialization using register-write sequences defined per device type
  • Continuous polling of identified devices at configurable intervals
  • Data publishing via the devjson and devbin topics
  • Bus health management including stuck-bus detection and recovery, and device hot-swapping

The bus runs its own dedicated FreeRTOS task so that scanning and polling activity does not block the main application loop.

I2C Implementation Selection

The I2C hardware driver is selected automatically based on the target chip:

Chip Driver used
ESP32, ESP32-S3, ESP32-C3, … RaftI2CCentral (Raft native driver)
ESP32-C6 RaftI2CCentral_ESPIDF (ESP-IDF v5 driver)

The selection can be overridden at build time by defining I2C_USE_RAFT_I2C or I2C_USE_ESP_IDF_5.

Configuration

I2C buses are declared inside the Buses array of the DevMan SysType configuration. The type field must be "I2C". All other fields in the bus object are I2C-specific.

{
    "DevMan": {
        "Buses": [
            {
                "name": "I2CA",
                "type": "I2C",
                "sdaPin": "SDA",
                "sclPin": "SCL",
                "i2cFreq": 400000
            }
        ]
    }
}

Core Parameters

Parameter Type Default Description
name string "" Bus name used to identify this bus in REST API calls (e.g. "I2CA").
sdaPin string SDA pin name (looked up via ConfigPinMap). Required.
sclPin string SCL pin name (looked up via ConfigPinMap). Required.
i2cPort int 0 ESP32 I2C hardware port number (0 or 1).
i2cFreq int 100000 I2C bus clock frequency in Hz. Common values: 100000 (standard), 400000 (fast), 1000000 (fast-plus).
i2cFilter int driver default Glitch filter level for the I2C bus (passed directly to the I2C driver).

Task Parameters

The bus runs in a dedicated FreeRTOS task. These parameters control its scheduling:

Parameter Type Default Description
taskCore int 1 CPU core to pin the task to (0 or 1).
taskPriority int driver default FreeRTOS task priority.
taskStack int driver default Task stack size in bytes.

Loop Timing Parameters

The I2C task yields periodically to allow other tasks to run. The unyield budgets control how long scanning is allowed to run before yielding again:

Parameter Type Default Description
loopYieldMs int driver default Milliseconds the task yields to other tasks each cycle via vTaskDelay.
fastScanMaxUnyieldMs int driver default Maximum milliseconds spent on fast scanning before yielding (internally converted to microseconds).
slowScanMaxUnyieldMs int driver default Maximum milliseconds spent on slow scanning before yielding (internally converted to microseconds).

Bus Scanning Parameters

These parameters control how the bus is scanned for devices. They are read directly from the bus configuration object (no prefix):

Parameter Type Default Description
busScanPeriodMs int ~20000 Period of the slow background scan in milliseconds.
scanBoost array of strings [] I2C addresses to promote to the highest scan priority (hex strings, e.g. "0x6a"). These are scanned more frequently and detected faster.

Bus Multiplexer Parameters (mux)

Multiplexer support (e.g. TCA9548A, PCA9548A) is configured under the mux key:

{
    "mux": {
        "enable": true,
        "minAddr": "0x70",
        "maxAddr": "0x77",
        "rstPin": 5,
        "clearCascadeMux": false
    }
}
Parameter Type Default Description
enable bool false Enable multiplexer support.
minAddr string "0x70" Lowest I2C address to probe for multiplexers.
maxAddr string "0x77" Highest I2C address to probe for multiplexers.
rstPin int -1 GPIO pin connected to the multiplexer hardware reset line. -1 = not used.
clearCascadeMux bool false Clear cascaded multiplexer slots when a multiplexer is detected.

Devices behind multiplexers are addressed using a slot number. See I2C Device Scanning for slot numbering details.

IO Expander Parameters (ioExps)

IO expanders connected to the I2C bus (used for bus power switching) are configured under the ioExps key. Refer to the IO expander documentation for specific fields.

Bus Power Controller Parameters (pwr)

An optional power controller allows Raft to power-cycle individual multiplexer slots for stuck-bus recovery. It is only instantiated if the pwr key is present as a JSON object:

{
    "pwr": {
        ...
    }
}

When present, the power controller setup is delegated to BusPowerController. Refer to the power controller documentation for specific fields.

Complete Configuration Example

The following example configures an I2C bus with a 400 kHz clock, a TCA9548A multiplexer, scan boost for two known device addresses, and a 30-second slow scan period:

{
    "DevMan": {
        "Buses": [
            {
                "name": "I2CA",
                "type": "I2C",
                "sdaPin": "SDA",
                "sclPin": "SCL",
                "i2cPort": 0,
                "i2cFreq": 400000,
                "taskCore": 1,
                "busScanPeriodMs": 30000,
                "scanBoost": ["0x6a", "0x36"],
                "mux": {
                    "enable": true,
                    "minAddr": "0x70",
                    "maxAddr": "0x77",
                    "rstPin": 5
                }
            }
        ]
    }
}

Bus Worker Task

The bus runs a background FreeRTOS task (I2CTask) that performs the following work each cycle, in order:

  1. Yield for loopYieldMs to allow other tasks to run
  2. Skip remaining work if a hiatus (deliberate pause) is active
  3. Bus scanning — if a scan is pending, service the scanner within the configured time budget
  4. Request queue — process any queued raw bus requests (from REST API calls etc.)
  5. Bus multiplexers — update multiplexer slot state
  6. Bus power controller — service power switching logic
  7. IO expanders — flush any pending output-state changes
  8. Device polling — poll all identified devices that are due
  9. Stuck-bus handler — check for and attempt recovery from stuck-bus conditions

The bus can be paused and resumed (e.g. during firmware update). While paused, scanning is suspended and polling is skipped, but queued requests are still processed.

Device Address Barring

Individual device addresses can be temporarily barred from access for a specified period (in milliseconds). This is used internally after commands that require a device to be left alone while processing (e.g. a soft reset). Barred addresses are skipped by both the scanner and the poller until the bar expires.

Related Documentation

Clone this wiki locally