Перейти к содержимому

i2c_bme280 — датчик на I2C

Сканирует шину I2C1, находит датчик Bosch BME280 (температура, давление, влажность) или BMP280 (без влажности) и печатает показания раз в 2 секунды. Драйвер — один файл без сторонних библиотек, формулы — из даташита.

Модуль датчика Доска-H723
VCC / VIN 3V3 (J1-3)
GND GND (J1-1)
SCL PB8 (J1-26)
SDA PB7 (J1-23)

Адрес 0x76, если вывод SDO модуля на GND, и 0x77 — если на 3,3 В; рецепт пробует оба.

Окно терминала
cmake --preset Release -DH723_RECIPES="i2c_bme280"

Без датчика (шина с подтяжками, никто не отвечает; задача ждёт датчик):

i2c_bme280: started
i2c_bme280: no devices on I2C1 (PB8 SCL, PB7 SDA)

С датчиком ожидается такой вывод (на живом BME280 на плате не проверялось):

i2c_bme280: device at 0x76
i2c_bme280: BME280 at 0x76
i2c_bme280: 24.31 C, 99012 Pa (742 mmHg), 41.5 %RH
  • Шина. I2C1 настроен в CubeMX (hi2c1, ~100 кГц). Подтяжек на плате нет — у модулей датчиков они свои; рецепт включает ещё встроенные (~40 кОм), чтобы шина без модуля не «висела в воздухе».
  • Сканер. HAL_I2C_IsDeviceReady посылает каждый адрес 0x08–0x77; ответил ACK — устройство есть. Полезно первым делом при любом новом датчике: виден адрес и что проводка цела.
  • Регистры. Датчик читается как память: HAL_I2C_Mem_Read(адрес, регистр, буфер, длина). 0xD0 — ID (0x60 BME280, 0x58 BMP280), 0x88…0xA1 и 0xE1…0xE7 — калибровка, 0xF7…0xFE — сырые измерения.
  • Калибровка. Каждый датчик на заводе прошит своими коэффициентами. Сырые числа АЦП без них бессмысленны; рецепт читает коэффициенты один раз при старте.
  • Компенсация. Целочисленные формулы из даташита (раздел 4.2.3): сначала температура (tFine), потом давление и влажность — они от неё зависят. Все 8 байт измерений читаются одной транзакцией, чтобы значения были из одного цикла измерения.
  • Режим. «Нормальный»: датчик сам меряет раз в секунду, прошивка просто читает последнее. Для батарейных устройств — «принудительный» (ctrl_meas с режимом 01) перед каждым чтением.
  • Таймауты. Все обмены по I2C — с таймаутом 10 мс: отвалившийся датчик даёт ошибку, а не зависание.
  • Другой датчик I2C — та же схема: i2cScan, чтение ID, readRegs/writeReg, формулы из его даташита.
  • Точнее и с меньшим шумом: передискретизация (биты osrs в 0xF2/0xF4) и фильтр IIR (0xF5).
  • Высота по давлению: h ≈ 44330 × (1 − (p / p0)^0.1903) м, p0 — давление на уровне моря.
  • Lua-модуль wire тоже работает с I2C1, но на PB8/PB9 — одновременно с рецептом его лучше не запускать.

Исходники рецепта: recipes/i2c_bme280