ESP32 и датчик BME280: температура, влажность и давление в Arduino IDE

Перевод статьи ESP32 with BME280 Sensor using Arduino IDE (Pressure, Temperature, Humidity) — Rui Santos & Sara Santos, Random Nerd Tutorials.
В этом руководстве подключим датчик BME280 к плате ESP32 и научимся считывать с него температуру, влажность, атмосферное давление, а заодно оценивать высоту над уровнем моря. Программировать ESP32 будем из Arduino IDE.
Знакомство с BME280#
BME280 измеряет сразу три величины — температуру, влажность и давление. Поскольку давление меняется с высотой, по нему можно грубо оценить и высоту над уровнем моря. Датчик компактный, недорогой и общается с микроконтроллером по двум интерфейсам на выбор: I2C или SPI.
Чаще всего встречаются модули с четырьмя выводами, рассчитанные только на I2C. Но бывают платы и с шестью выводами, которые поддерживают оба протокола — I2C и SPI.
Что понадобится#
- плата ESP32 (о выборе и настройке — ниже);
- датчик BME280;
- макетная плата;
- соединительные провода.
Предварительная настройка#
Чтобы прошивать ESP32 из Arduino IDE, в ней должна быть установлена поддержка плат ESP32:
Схема подключения — BME280 по I2C#
Проще всего работать с BME280 по I2C. У ESP32 для этого есть стандартные выводы: GPIO 22 (SCL) и GPIO 21 (SDA).
| BME280 | ESP32 |
|---|---|
| Vin | 3.3V |
| GND | GND |
| SCL | GPIO 22 |
| SDA | GPIO 21 |

BME280 по I2C: SDA → GPIO 21, SCL → GPIO 22.
Если у вас модуль на шесть выводов (с поддержкой SPI и I2C), для работы по I2C используйте только линии тактирования и данных:
| BME280 | ESP32 |
|---|---|
| SCK (вывод SCL) | GPIO 22 |
| SDI (вывод SDA) | GPIO 21 |
Схема подключения — BME280 по SPI#
Если вам удобнее SPI, шестивыводной модуль подключается к стандартным выводам SPI у ESP32:
| BME280 | ESP32 |
|---|---|
| SCK | GPIO 18 |
| SDO (MISO) | GPIO 19 |
| SDI (MOSI) | GPIO 23 |
| CS | GPIO 5 |
Установка библиотек#
Чтобы читать показания BME280, установим библиотеки от Adafruit. Откройте в Arduino IDE Менеджер библиотек и установите:
- Adafruit BME280 — работа с датчиком;
- Adafruit Unified Sensor — зависимость, которую нужно доустановить отдельно.
Код для чтения показаний#
Следующий скетч считывает температуру, давление, влажность и приблизительную высоту и выводит их в монитор порта. По умолчанию код рассчитан на I2C — строки для SPI закомментированы, при необходимости их можно раскомментировать.
/*********
Complete project details at https://randomnerdtutorials.com
*********/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
/*#include <SPI.h>
#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
unsigned long delayTime;
void setup() {
Serial.begin(9600);
Serial.println(F("BME280 test"));
bool status;
// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
Serial.println("-- Default Test --");
delayTime = 1000;
Serial.println();
}
void loop() {
printValues();
delay(delayTime);
}
void printValues() {
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
// Convert temperature to Fahrenheit
/*Serial.print("Temperature = ");
Serial.print(1.8 * bme.readTemperature() + 32);
Serial.println(" *F");*/
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.println();
}
Как это работает#
Разберём ключевые места скетча.
Сначала подключаются библиотеки: Wire.h для шины I2C, а также Adafruit_Sensor.h и Adafruit_BME280.h для работы с датчиком.
Константа задаёт давление на уровне моря — оно нужно, чтобы оценить высоту:
#define SEALEVELPRESSURE_HPA (1013.25)
Затем создаётся объект bme для общения по I2C:
Adafruit_BME280 bme; // I2C
В setup() запускается монитор порта на скорости 9600 бод и инициализируется датчик. Обратите внимание на адрес 0x76 — это стандартный I2C-адрес большинства модулей BME280. Если ваш датчик не находится, попробуйте адрес 0x77:
status = bme.begin(0x76);
Само чтение показаний собрано в функции printValues():
bme.readTemperature()— температура в градусах Цельсия;bme.readPressure() / 100.0F— давление в гектопаскалях (гПа); делим на 100, потому что метод возвращает значение в паскалях;bme.readAltitude(SEALEVELPRESSURE_HPA)— приблизительная высота над уровнем моря в метрах;bme.readHumidity()— относительная влажность в процентах.
В коде также есть закомментированный блок, который переводит температуру в градусы Фаренгейта:
/*Serial.print("Temperature = ");
Serial.print(1.8 * bme.readTemperature() + 32);
Serial.println(" *F");*/
Результат#
Загрузите скетч в ESP32. Затем откройте монитор порта на скорости 9600 бод и нажмите на плате кнопку RST (сброс). В окне монитора начнут появляться свежие показания температуры, давления, высоты и влажности — они обновляются раз в секунду.
Что дальше#
Теперь у вас есть базовый скетч, который читает с BME280 сразу четыре величины. На его основе удобно строить что-то большее: выводить данные на веб-страницу, вести журнал показаний на microSD-карту или собрать полноценную метеостанцию.