Домашний график погоды на DHT22 полгода показывал мне температуру и влажность, и я был доволен, пока не пришёл циклон. За окном стихло, стрелка барометра на стене упала, а мой график остался слепым: давления в списке измерений DHT22 нет вообще. Я заказал BME280, вскрыл пакетик с крошечной платкой на шесть контактов и подключил её по привычке, как DHT: питание, земля, один провод данных на цифровой пин. Сенсор молчал. Я менял пин, переустанавливал библиотеку, перетыкал провода — тишина, пока до меня не дошло: BME280 не умеет разговаривать по одному проводу. Он живёт на шине I2C, и схему для него рисуют заново, а не адаптируют от DHT.
В этом уроке соберём схему правильно с первого раза: два провода данных, честный адрес модуля, библиотека Adafruit BME280. Снимем с чипа все три величины, посчитаем высоту над уровнем моря по давлению и разберёмся, почему под именем BME280 с маркетплейсов приезжает родня без гигрометра — и как её распознать до паяльника, а не после.
Шина I2C: два провода вместо отдельного пина
I2C — это шина из двух сигнальных линий: SDA с данными и SCL с тактом. На Uno и Nano это фиксированные пины A4 и A5 — не произвольные, потому что за ними спрятан аппаратный контроллер. Если вы уже подключали экран по I2C, вы держали эту шину в руках: у LCD 16x2 на модуле I2C ровно те же SDA и SCL. Устройств на двух проводах может висеть несколько — каждому выделяется свой адрес, и в этом главная прелесть шины, о которой мы подробно говорили в уроке про I2C.
У модуля GY-BME280 шесть контактов. VIN и GND — питание. SCL и SDA — шина. Оставшиеся два ведут себя скромно: CS при работе по I2C не нужен, его оставляют неподключенным или прижимают к питанию, а вот SDO важен — он выбирает адрес. SDO к земле — модуль отвечает на адресе 0x76; SDO к питанию или в воздухе — на 0x77. Библиотека Adafruit по умолчанию стучится на 0x77, поэтому типовой сценарий новичка звучит так: скетч возвращает false из begin(), автор винит проводку, а на деле модуль сидит на 0x76. Я теперь не угадываю, а запускаю сканер I2C-адресов — он за пять секунд печатает адрес любого нового устройства.
С питанием аккуратнее, чем с остальным. Сам чип BME280 трёхвольтовый: подать на него 5 В напрямую — способ получить сувенир. Спасает взгляд на плату: если на модуле, кроме чипа, стоит маленький корпус стабилизатора с маркировкой вида 662K и пара резисторов — такому модулю можно 5 В, он сам себе понизит. Если на плате только голый чип — питание строго 3,3 В. Это моё правило, и оно ни разу меня не подвело: полминуты разглядывания платы дешевле одного сгоревшего сенсора.
Три величины с одного чипа
BME280 измеряет температуру от −40 до +85 °C с шагом 0,01 °C; заявленная точность — около ±0,5 °C при комнатных условиях, дальше от середины диапазона она сползает к ±1. Влажность — от 0 до 100 % с точностью ±3 % в середине шкалы, и это заметно честнее DHT22, чьи показания к краям диапазона гуляют сильнее. Давление — от 300 до 1100 гПа, это весь земной ассортимент: от глубокой депрессии до высоты в горах. Абсолютная точность ±1 гПа, но относительная — как меняется давление от замера к замеру — ±0,12 гПа, и вот эта вторая цифра и есть подарок.
Переведу гектопаскали на человеческий. В приземном слое давление падает примерно на 0,12 гПа с каждым метром подъёма — то есть сенсор различает первый и второй этаж вашей девятиэтажки. А ±1 гПа абсолютной погрешности — это плюс-минус метров восемь-девять высоты: для прогноза погоды прекрасно, для точной высотомерной привязки — с оговорками. Все три величины снимаются за миллисекунды, и никаких ограничений по частоте опроса, как у DHT, здесь нет: DHT22 пересчитывает значения внутри корпуса раз в две секунды, а BME280 готов отвечать хоть десять раз в секунду.
Отдельный козырь — питание. В работе чип берёт меньше миллиампера, во сне — единицы микроампер. Для метеоточки на батарейках это разница между неделей и сезоном работы. Я сравнивал выбор сенсоров подробно в уроке DHT11 против DHT22: там же вспомнил BME280 как дорогого соседа — теперь у нас встреча личная. Моё мнение с границей: если в комнате нужно «тепло или сыро» глазами человека — берите DHT11 и не платите вчетверо больше. Если нужны давление, высота, честная влажность, батарейный режим или десятая доля градуса — вот теперь BME280 оправдан.
| Величина | Диапазон | Точность | Что это значит |
|---|---|---|---|
| Температура | −40…+85 °C | ±0,5 °C при 25 °C | шаг 0,01 °C, но верьте десятым |
| Влажность | 0–100 % | ±3 % в середине шкалы | честнее DHT22 у краёв диапазона |
| Давление | 300–1100 гПа | ±1 гПа абс., ±0,12 гПа отн. | 1 гПа ≈ 8 м высоты; этаж различит |
| Ток | — | <1 мА в работе | микроамперы во сне — для батареек |
Высота по давлению: формула и её подвох
Барометр — это ещё и альтиметр, и формула преобразования короткая: h = 44330 × (1 − (p/1013,25)^0,1903), где p — измеренное давление в гектопаскалях, а 1013,25 — среднее давление на уровне моря. Подставьте показания сенсора — и в мониторе порта появится высота. Первый запуск у меня вызвал недоумение: я живу на шестом этаже, а датчик сообщил про минус 140 метров. Подвох в том, что 1013,25 — это табличное среднее, а реальное давление у поверхности сегодня может быть и 985, и 1035 гПа, и каждый гектопаскаль погоды уводит расчёт на восемь метров.
Лекарство — подставлять вместо константы текущее давление на уровне моря, приведённое к вашим координатам: метеослужбы называют его QNH и обновляют несколько раз в день. Тогда расчёт успокаивается и начинает показывать разумные метры. Но для моих задач я чаще использую даже не абсолютную высоту, а разницу: вычесть из текущего давления утренний замер на том же месте — и увидеть, как прибыло или убыло воздуха. Разностный подход ±0,12 гПа ловит уверенно, а погода в константе не мешает. Кстати, влажность с BME280 тоже живёт в расчётах — например, точка росы по формуле Магнуса считается с ней в отдельном уроке про точку росы.
Ставится библиотека через менеджер — как ставить библиотеки в IDE, я разбирал в уроке про библиотеки: ищите Adafruit BME280 Library, а заодно согласитесь на установку Adafruit Unified Sensor — без неё скетч не соберётся. В скетче три вызова: begin() с адресом, readTemperature() с readHumidity() и readPressure(), который возвращает паскали — делим на сто, чтобы получить привычные гектопаскали. Для неблокирующего цикла без delay посмотрите урок про millis, а здесь для простоты оставлю паузу:
#include <Wire.h>#include <Adafruit_Sensor.h>#include <Adafruit_BME280.h> Adafruit_BME280 bme; #define SEALEVELPRESSURE_HPA 1013.25 // сюда подставляйте текущий QNH void setup() { Serial.begin(9600); // SDO на GND -> адрес 0x76; в воздухе или на VCC -> 0x77 if (!bme.begin(0x76)) { Serial.println("BME280 ne naiden: provoda ili adres"); while (1) delay(10); }} void loop() { float t = bme.readTemperature(); // градусы float h = bme.readHumidity(); // проценты float p = bme.readPressure() / 100.0F; // паскали -> гПа float alt = bme.readAltitude(SEALEVELPRESSURE_HPA); Serial.print("t="); Serial.print(t); Serial.print(" h="); Serial.print(h); Serial.print(" p="); Serial.print(p); Serial.print(" alt="); Serial.println(alt); delay(2000);}- 1. У модуля BME280 ножка SDO прижата к земле. С каким адресом его указывать в begin()?
- 2. Альтиметр по формуле с константой 1013,25 гПа показывает −140 м на шестом этаже. Почему?
- 3. readHumidity() держит ровно 0.00 при живых температуре и давлении. Что это значит?
- 4. Почему BME280 выгоднее DHT22 для метеостанции на батарейке?
- 5. С какой частотой можно опрашивать BME280?
- BME280 живёт на I2C: SDA — A4, SCL — A5 на Uno/Nano, отдельный пин данных не нужен.
- SDO на GND — адрес 0x76, в воздухе или на VCC — 0x77; библиотека Adafruit по умолчанию ищет 0x77, адрес указывайте явно.
- Температура −40…+85 °C, влажность 0–100 % с ±3 %, давление 300–1100 гПа; 1 гПа ≈ 8 м высоты.
- Для честной высоты подставляйте текущее QNH вместо константы 1013,25 — иначе погода гуляет сотнями метров.
- Влажность навсегда 0.00 — у вас BMP280 в коробке от BME280.
Частые вопросы по теме урока
- У модуля BME280 ножка SDO прижата к земле. С каким адресом его указывать в begin()?
- SDO — ножка выбора адреса: к земле — 0x76, к питанию или в воздухе — 0x77. Библиотека Adafruit по умолчанию стучится на 0x77, поэтому адрес стоит указывать явно. 0x76 — SDO на GND выбирает младший адрес
- Альтиметр по формуле с константой 1013,25 гПа показывает −140 м на шестом этаже. Почему?
- 1013,25 — климатическое среднее, а не сегодняшний день. Погода уводит давление на ±20–30 гПа, то есть на сотни метров расчётной высоты. Лечится подстановкой текущего QNH с метеослужбы. Реальное давление у поверхности меняется погодой на десятки гПа от табличного среднего
- readHumidity() держит ровно 0.00 при живых температуре и давлении. Что это значит?
- Ноль влажности при работающих остальных каналах — фирменный симптом BMP280 в упаковке BME280. Дальше либо менять библиотеку на BMP280, либо менять сенсор. Под видом BME280 продан BMP280 — гигрометра в чипе нет
- Почему BME280 выгоднее DHT22 для метеостанции на батарейке?
- DHT22 греет внутренний сенсор при каждом измерении и в спячку не умеет. BME280 в работе берёт меньше 1 мА, а во сне — единицы мкА: на батарейках это сезоны вместо недель. Ток измерения меньше миллиампера, во сне — микроамперы
- С какой частотой можно опрашивать BME280?
- Ограничение DHT — время внутреннего пересчёта. У BME280 его нет: измерение занимает миллисекунды, частота опроса диктуется вашей задачей, а не сенсором. Ограничений типа DHT нет — значения готовы за миллисекунды