Skip to content

feat: BME280 environmental sensor on the new i2c_master API (PR-03)#11

Merged
cryptotomte merged 5 commits into
mainfrom
005-bme280-i2c
Jul 2, 2026
Merged

feat: BME280 environmental sensor on the new i2c_master API (PR-03)#11
cryptotomte merged 5 commits into
mainfrom
005-bme280-i2c

Conversation

@cryptotomte

Copy link
Copy Markdown
Owner

Summary

Ports the BME280 environmental sensor (temperature/humidity/pressure) from the Adafruit library to a self-contained driver on ESP-IDF's new i2c_master API, per specs/005-bme280-i2c/ (spec, plan, contracts, data model). Implements FR3 of the migration PRD.

  • Bme280Sensor (pure C++, host-tested): 0x76/0x77 address probing with chip-ID verification, calibration readout (incl. split-nibble H4/H5), Bosch datasheet compensation (int32 T / int64 P / int32 H), parity sampling profile (NORMAL mode, T×2/P×16/H×1, IIR ×16, standby 500 ms — like-for-like with the Arduino unit), lazy re-init and automatic recovery after sensor loss.
  • EspI2cBus (target-only): owns the single shared i2c_master bus on board pins at 100 kHz, mutex-guarded device-handle table — PR-05's INA226 attaches to the same instance.
  • New interfaces IEnvironmentalSensor / II2cBus (soil-sensor conventions: gate on read(), last-good values, NaN placeholders before first success, live availability probe).
  • App integration: 5 s sensor task with host-tested bounded log cadence (SensorTaskLogPolicy), env console command (HIL path), wiring after pumps_force_off().
  • No new managed dependencies — the espressif/bme280 registry component was rejected (floating i2c_bus: "*" dependency, bus-ownership conflict with the shared-bus requirement, un-host-testable compensation); dependencies.lock unchanged.
  • Deliberate divergences from legacy documented in docs/parity-checklist.md §6 (address probing, last-good getters, live availability, synchronized access).

Full review cycle completed (5 agents + fix pass + verification re-review, CLEAN): findings and outcomes tracked in the spec directory; notable catch — IDF v6 returns ESP_ERR_INVALID_RESPONSE (not ESP_ERR_NOT_FOUND) for transaction NACKs, verified against the pinned container.

Test plan

  • Host suite 119/0 on the linux preview target (40 BME280 tests: Bosch reference vectors incl. datasheet worked example, negative-temperature and extreme-raw vectors, init/read error paths, address-variant matrix, recovery with calibration re-read, log-policy cadence, mock coherence, Locked delegation)
  • rev1 + rev2 build green from clean checkout in espressif/idf:v6.0.1
  • dependencies.lock unchanged
  • HIL on the rev1 bench rigspecs/005-bme280-i2c/checklists/hil.md (A: 5 s readings + Arduino agreement ±0.5 °C/±3 %RH/±1 hPa; B: env command; C: unplug/replug + sensorless boot + C6 log classification; D: 0x76 module swap if hardware available; E: pump/soil regression guard)

Do not merge before HIL is green — the BME280 is mounted on the bench rig, so HIL is expected for this PR (results as a PR comment, pattern from #7).

🤖 Generated with Claude Code

cryptotomte and others added 5 commits July 2, 2026 16:14
…280-i2c)

Full spec-kit artifact set for PR-03: feature spec with CP1 clarifications
(parity NORMAL-mode sampling profile; env-only 5 s sensor task), research
R1-R10 (own Bosch compensation code over espressif/bme280 registry
component; verified i2c_master bus lock and legacy driver status on IDF
v6.0.1), data model, interface contracts, quickstart and 25 tasks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nd 5 s sensor task

Pure-logic Bme280Sensor (0x76/0x77 probing, chip-ID check, Bosch datasheet
compensation, parity NORMAL-mode sampling profile) behind new
IEnvironmentalSensor/II2cBus interfaces; EspI2cBus owns the shared master
bus (100 kHz, board pins) for PR-05 reuse; LockedEnvironmentalSensor
decorator, MockI2cBus, env console command and app-level 5 s sensor task.
Host suite extends to 86 tests incl. Bosch reference vectors (T002-T012,
T021).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… and docs

US2-US4 + polish: host-testable sensor-task log policy
(SensorTaskLogPolicy, bounded WARN cadence), MockEnvironmentalSensor with
consistency helpers, 23 new host tests (error paths incl.
calibration-re-read on module swap, 0x76/0x77 address matrix, negative-
temperature and extreme-raw Bosch reference vectors, log policy, mock
coherence) - suite 109/0. firmware/CLAUDE.md section, parity-checklist §6
divergences, HIL checklist. Full verification: rev1+rev2 green from clean,
dependencies.lock unchanged (T013-T025).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… test hardening

Review findings A1-A5, B1-B9, C1-C4+C8: infrastructure I2C failures now
ESP_LOGE/WARN instead of compiled-out debug (wedged bus distinguishable
from absent device); bounded init-failure logging (sensorless boot no
longer WARNs every 5 s); NaN pre-first-read placeholders (self-announcing
for non-gating consumers); MockEnvironmentalSensor initialize() reports
error codes like the real driver; MockI2cBus wrap-around UB fixed;
EspI2cBus handle table mutex-guarded for PR-05 multi-task sharing; env
command concurrent-state hint; error-code docs corrected (mid-init error
2, loss sequence 2-then-1); 10 new host tests (init-failure branches,
chip-ID fallthrough, digP1=0 guard, nonzero H3 / negative H5-H6 vectors,
clamps, Locked delegation, foreign chip-ID) — suite 119/0, rev1+rev2
green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Re-review finding: i2c_master_transmit(_receive) return
ESP_ERR_INVALID_RESPONSE on a device NACK in IDF v6 (ESP_ERR_NOT_FOUND is
probe-only), so the expected-NACK debug branch in readRegisters/
writeRegister was dead code and unplug NACKs logged at WARN. Classify
ESP_ERR_INVALID_RESPONSE as expected-NACK; add HIL item C6 pinning the
no-WARN-flood behavior on hardware (target-only path, not host-testable).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cryptotomte cryptotomte merged commit 93fdd39 into main Jul 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant