BMP280 приехал ко мне в конверте размером с ноготь: VCC, GND, SDA, SCL — четыре провода и никакой магии. Я подключил модуль к Uno, залил первый попавшийся пример и увидел температуру 0.00 и давление 0.00 Па. Скетч был чужой, датчик мой, и три вечера я подозревал подделку, пока не открыл чужой код построчно и не заметил: в примере жёстко прописан адрес 0x77, а мой модуль отвечал на 0x76. Одна цифра в begin() — и всё ожило. В тот день я понял, где кончаются примеры из интернета и начинается datasheet.
Дальше случилось второе открытие: захотелось мне убрать дрожь давления при сквозняке, а в примерах к библиотеке про это ни слова. Ответ жил в PDF на полсотни страниц, в таблице с адресами регистров и битовой диаграммой. В этом уроке покажу, как я читаю datasheet: где искать карту регистров, как расшифровывать битовые поля и как дотянуться до всего этого голым Wire, без библиотек. Симулятор уже поставил на шину датчик-заглушку: байты он отдаёт фиксированные, зато протокол — настоящий. Если чтение DHT по одному проводу мы ловили микросекундными паузами, здесь всё пристойнее: шина сама разруливает, где данные.
Моё правило с тех пор: купил новый датчик — первые пятнадцать минут только на карту регистров, и лишь потом примеры. Это звучит скучно, пока не заметишь обратное: без карты чужой пример диктует, что думать, и любая его неточность становится твоей. С картой наоборот — примеры читаются как открытая книга, и сразу видно, где автор упростил: выкинул проверку статуса, зашил чужой адрес, забыл про режим сна между измерениями.
Datasheet — это таблица, а не роман
Любой I2C-датчик — пачка адресованных ячеек, регистров. Пишешь по адресу команду — датчик настраивается; читаешь по адресу — получаешь измерение. Ячейки у BMP280 восьмибитные, по байту на адрес, — у некоторых чипов регистры бывают и шестнадцатибитными, это видно по карте. У BMP280 карта компактная: служебный идентификатор в 0xD0, статус в 0xF3, настройки в 0xF4 и 0xF5, сырые данные с 0xF7. Калибровочные коэффициенты лежат с 0x88 по 0xA1 — их прошивает Bosch на заводе, и у каждого экземпляра они свои. Как найти адрес самого модуля на шине, я разбирал в сканере I2C-адресов, а механику обмена стартами и стопами — в уроке про мастера и слейва.
В datasheet мне нужны ровно три вещи. Первая — таблица Register map: весь перечень регистров одной колонкой. Вторая — страница конкретного регистра: там нарисована битовая диаграмма, из которой видно, какой бит за что отвечает. Третья — электрические параметры: у BMP280 диапазон измерений 300–1100 гПа, температура от −40 до +85 °C, а голый чип питается от 1,71 до 3,6 В — модуль со стабилизатором терпит 5 В, чип без обвязки на 5 В сгорает.
По самому PDF удобно ходить по оглавлению, не читая подряд: первые страницы — характеристики и распиновка, середина — физика измерения, а карта регистров и описания битов живут ближе к концу, в разделе про интерфейсы. Я в первый раз прочитал datasheet как роман от первой страницы — и утонул в главе про компенсацию влажности, которой у BMP280 нет: спутал с BME280. С тех пор беру оглавление, нахожу Register map и иду от неё в обе стороны — на всё про всё уходит минут двадцать вместо вечера.
| Адрес | Имя | Что лежит | Сколько байтов |
|---|---|---|---|
| 0xD0 | chip id | подпись чипа: на живом BMP280 здесь 0x58, у BME280 — 0x60 | 1 |
| 0xF3 | status | бит 3 — «измерение идёт», бит 0 — «идёт обновление калибровки» | 1 |
| 0xF4 | ctrl_meas | биты 7:5 — осреднение температуры, 4:2 — давления, 1:0 — режим | 1 |
| 0xF5 | config | биты 7:5 — пауза между измерениями, 4:2 — фильтр | 1 |
| 0xF7–0xF9 | давление | 20 значащих бит: старший, средний, 4 бита хвоста | 3 |
| 0xFA–0xFC | температура | те же 20 бит, тот же порядок байтов | 3 |
| 0x88–0xA1 | калибровка | заводские коэффициенты пересчёта, читаются при старте | 22 |
Битовые диаграммы читаются слева направо, от старшего бита к младшему. Открываем описание регистра 0xF4 ctrl_meas: биты 7:5 — осреднение температуры, биты 4:2 — осреднение давления, биты 1:0 — режим. Трёхбитное поле умеет восемь значений: 000 — измерение отключено, 001 — один отсчёт, 010 — два, и так до 101 — шестнадцать отсчётов. Режим 00 укладывает датчик спать, 01 и 10 — разовое измерение по команде, 11 — нормальный режим: датчик меряет сам, по расписанию из регистра 0xF5.
Пример сборки своими руками: температура ×1 (001), давление ×4 (100), режим normal (11). Выписываю поля подряд: 001 100 11 — и получаю байт 0b00110011, то самое число, которое предстоит записать в 0xF4. Адрес модуля тоже решается одним выводом: SDO на землю — 0x76, к питанию — 0x77. У дешёвых модулей SDO часто висит в воздухе, и адрес зависит от партии — второй повод держать сканер под рукой после моей истории с 0x77.
К осреднению есть свой торг, и он прописан в тех же битах. Больше отсчётов — тише число, но дольше преобразование: при ×16 по обеим величинам датчик занимает до 45 мс, при ×1 укладывается в миллисекунды. Для метеостанции, где опрос раз в секунду, осреднение ×1 плюс встроенный фильтр из регистра 0xF5 — биты 4:2, коэффициенты 2, 4, 8 и 16 — даёт гладкую кривую без потери темпа. А для высотомера, где каждая сотня миллисекунд на счету, я выбирал между ×2 и ×4 и всегда останавливался на ×4: шум падает вдвое, а время растёт незначительно.
Протокол разговора с регистром
Чтение регистра — двухтактный обмен, тот же, что мы отрабатывали на двух платах по I2C. Первый такт: beginTransmission(0x76), write(0xD0), endTransmission() — мастер назвал адрес ячейки и отпустил шину. Второй такт: requestFrom(0x76, 1) и read() — забираем байт. Рисунок один и тот же у всех устройств на шине — от часов DS3231 до OLED: меняется адрес и карта регистров, протокол остаётся.
Зачем читать статус 0xF3: бит 3 поднимается, пока датчик ведёт измерение. При осреднении ×16 по обеим величинам преобразование длится до 45 мс — если в этот момент дёргать шину запросом данных, получите прошлое измерение. Мой цикл для неторопливых опросов: выставил конфиг, подождал 50 мс, пошёл мерить. Бит 0 сообщает, что датчик копирует калибровку из своей памяти — это случается после подачи питания, в первые миллисекунды.
Приятная деталь про многобайтовое чтение: регистры данных у BMP280 идут подряд, 0xF7, 0xF8, 0xF9 и дальше, поэтому один requestFrom(ADDR, 6) приносит сразу давление и температуру — адрес регистра у чипа сам инкрементируется с каждым принятым байтом. Проверьте это поведение в документации вашего датчика: не у всех оно есть, и если адрес не ползёт, придётся запрашивать каждый регистр своей парой «адрес — чтение». Именно так я когда-то трижды запрашивал у DS1307 один и тот же байт, пока не прочитал строчку про burst-режим.
#include <Wire.h> const byte ADDR = 0x76; // у моего модуля 0x76; SDO к питанию — 0x77 byte readRegister(byte reg) { // два такта: адрес регистра, затем чтение Wire.beginTransmission(ADDR); Wire.write(reg); Wire.endTransmission(); Wire.requestFrom(ADDR, 1); if (Wire.available() > 0) return Wire.read(); return 0;} void setup() { Wire.begin(); Serial.begin(9600); Serial.print("id="); Serial.println(readRegister(0xD0), HEX); // живой BMP280 ответит 0x58 byte st = readRegister(0xF3); // статус Serial.print("status="); Serial.println(st, BIN); Serial.print("measuring="); Serial.println((st >> 3) & 0b1); // бит 3: идёт измерение} void loop() { delay(1000);}Теперь честно про цифры в симуляторе: заглушка движка на каждый запрошенный байт отвечает 42 — это 0b00101010, или 0x2A. Математика над байтами при этом настоящая: сдвиг и маска честно вытащили бит 3 из сорока двух и получили единицу — «измерение идёт». На живом BMP280 регистр 0xD0 вернёт 0x58 — фирменную подпись чипа; у родственника BME280 подпись 0x60, по ней семейство различают на первом же скане.
Если на реальной плате вместо подписи приходят 0xFF или 0x00 — до датчика никто не доехал. Причин обычно четыре: перепутанные местами SDA и SCL, нет общего провода земли, неверный адрес, оборванная подтяжка. Первым делом я запускаю сканер адресов: он за две секунды сужает поиск до монтажа или до кода, и дальше datasheet уже не при чём.
Подпись из 0xD0 — ещё и бесплатный тест на родство. Ответ 0x58 — перед вами BMP280; 0x60 — BME280, и у него в карте регистров появился влажный блок: данные влажности лежат с 0xFD по 0xFE. Я как-то полчаса искал в BMP280 регистр влажности, потому что купил модуль по картинке из чужого проекта, а приехал сосед. С тех пор чтение 0xD0 — мой первый байт на любой новой плате: дешевле проверить подпись, чем строить схемы на воображаемом чипе.
- Карта регистров — первая таблица datasheet: у BMP280 ID в 0xD0, статус в 0xF3, конфигурация в 0xF4–0xF5, сырые данные с 0xF7
- Битовые поля читаются слева направо от старшего бита; байт конфигурации собирают руками: 001 100 11 → 0b00110011
- Обмен с регистром двухтактный: write адреса → стоп → requestFrom → read; между тактами шина свободна
- Бит 3 статуса 0xF3 поднят, пока идёт измерение — до 45 мс при осреднении ×16
- На живом BMP280 регистр 0xD0 возвращает 0x58; 0xFF или 0x00 — проверяйте землю, SDA/SCL, адрес и подтяжку
- 1. Что лежит в регистре 0xD0 у BMP280?
- 2. Бит 3 в регистре 0xF3 сообщает, что…
- 3. Как правильно прочитать регистр датчика?
- 4. Вывод SDO модуля притянут к земле. Адрес датчика?
- 5. Сколько байтов занимает сырая температура в 0xFA–0xFC?
Частые вопросы по теме урока
- Что лежит в регистре 0xD0 у BMP280?
- 0xD0 — chip id: подпись BMP280 равна 0x58, у BME280 — 0x60. Калибровка живёт с 0x88, данные — с 0xF7. Я читаю 0xD0 первым на любой новой плате: это дешевле, чем строить схему на воображаемом чипе. Идентификатор чипа: на живом датчике 0x58
- Бит 3 в регистре 0xF3 сообщает, что…
- Бит 3 «measuring» поднят, пока идёт преобразование — до 45 мс при осреднении ×16 по обеим величинам. идёт измерение
- Как правильно прочитать регистр датчика?
- Двухтактный обмен: адрес регистра уходит отдельной передачей, чтение — отдельным requestFrom. Между тактами шина свободна, и в панели симулятора видно, как между ними проходит стоп-условие. Сначала write адреса регистра, потом requestFrom и чтение
- Вывод SDO модуля притянут к земле. Адрес датчика?
- SDO на землю — 0x76, к питанию — 0x77. Для сравнения: 0x68 занята часами DS3231, 0x27 — переходником LCD. 0x76
- Сколько байтов занимает сырая температура в 0xFA–0xFC?
- Три байта: старший, средний и 4 младших бита хвоста — всего 20 значащих бит. Тот же формат у давления в 0xF7–0xF9. 3 байта, значащих бит — 20