Программирование ARM ESP-IDF: чтение датчика BME280 Sun, July 19 2026  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


ESP-IDF: чтение датчика BME280 Печать
Добавил(а) microsin   

Пример кода для чтения данных с датчика BME280 на ESP32-C3 в ESP-IDF v5.4.1 можно реализовать, используя официальные компоненты из реестра Espressif. Ниже приведен пример с использованием компонента espressif/bme280.

[Подготовка проекта]

1. Создайте проект:

idf.py create-project bme280_example
cd bme280_example

2. Добавьте зависимость от компонента драйвера bme280. Выполните команду в корне проекта, чтобы добавить в проект официальный драйвер BME280:

idf.py add-dependency "espressif/bme280=*"

3. Настройте выводы GPIO в конфигурации. Для ESP32-C3 в этом драйвере по умолчанию используются следующие выводы портов:

SDA: GPIO1
SCL: GPIO2

Вы можете изменить их в файле main.c. Например, замените содержимое main/main.c следующим кодом:

#include < stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/i2c.h"
#include "bme280.h"

// Настройка портов I2C для ESP32-C3, их можно изменить при необходимости:
#define I2C_MASTER_SCL_IO GPIO_NUM_2
#define I2C_MASTER_SDA_IO GPIO_NUM_1

#define I2C_MASTER_NUM I2C_NUM_0 // Номер порта I2C
#define I2C_MASTER_FREQ_HZ 100000 // Частота I2C
#define BME280_ADDR BME280_I2C_ADDRESS_DEFAULT // Адрес 0x76

static const char *TAG = "BME280_EXAMPLE";

// Дескрипторы шины I2C и датчика:
static i2c_bus_handle_t i2c_bus = NULL;
static bme280_handle_t bme280 = NULL;

void app_main(void) { // Шаг 1: Инициализация I2C шины
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_bus = i2c_bus_create(I2C_MASTER_NUM, &conf);
if (i2c_bus == NULL) {
ESP_LOGE(TAG, "I2C bus creation failed");
return;
}

// Шаг 2: Инициализация датчика BME280
bme280 = bme280_create(i2c_bus, BME280_ADDR);
if (bme280 == NULL) {
ESP_LOGE(TAG, "BME280 creation failed");
return;
}

// Выполняем инициализацию с настройками по умолчанию
esp_err_t ret = bme280_default_init(bme280);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "BME280 default init failed: %d", ret);
return;
}

ESP_LOGI(TAG, "BME280 initialized successfully!");

// Шаг 3: Основной цикл чтения данных
float temperature = 0.0, humidity = 0.0, pressure = 0.0;
while (1) {
// Читаем данные с датчика
bme280_read_temperature(bme280, &temperature);
bme280_read_humidity(bme280, &humidity);
bme280_read_pressure(bme280, &pressure);

ESP_LOGI(TAG, "Temperature: %.2f °C", temperature);
ESP_LOGI(TAG, "Humidity: %.2f %%", humidity);
// Переводим паскали в гектопаскали:
ESP_LOGI(TAG, "Pressure: %.2f hPa", pressure / 100.0);
ESP_LOGI(TAG, "------------------------");

// Ждем 2 секунды перед следующим измерением:
vTaskDelay(pdMS_TO_TICKS(2000));
} }

[Сборка и прошивка]

4. Соберите проект и прошейте его на плату:

idf.py build flash monitor

После того, как программа запустится, в консоли монитора вы увидите вывод показаний температуры, влажности и давления.

[Важные замечания]

● Убедитесь, что датчик BME280 подключен правильно: VCC к шине 3.3V, GND к шине земли, SDA к GPIO1, SCL к GPIO2. Подтягивающие резисторы на линиях I2C уже включены в коде (GPIO_PULLUP_ENABLE). Однако если шина I2C имеет повышенную емкость, или к ней подключены дополнительно другие устройства, то возможно потребуется добавить внешние нагрузочные pull-up резисторы номиналом от 4.7 кОм до 10 кОм.

● Адрес датчика: gо умолчанию используется адрес 0x76. Если ваш датчик использует адрес 0x77, то замените BME280_I2C_ADDRESS_DEFAULT на BME280_I2C_ADDRESS_SECONDARY.

● Точность измерений: для повышения точности рекомендуется размещать датчик подальше от платы ESP32-C3, так как она нагревается и может искажать показания температуры.

[Отличие датчиков BMP280 и BME280]

Основное и самое важное отличие между датчиками BMP280 и BME280 заключается в том, что BME280 измеряет влажность воздуха, а BMP280 — нет. По сути, BME280 — это BMP280 с дополнительным датчиком влажности.

Вот их сравнение в таблице для наглядности:

Характеристика BMP280 BME280
Измеряемые параметры Температура и атмосферное давление Температура, атмосферное давление и влажность
Точность измерения давления ±1.0 гПа (абсолютная) ±1.0 гПа (абсолютная, по некоторым данным ±1.7 гПа)
Точность измерения влажности - ±3% (относительная влажность)
Цена (июль 2026 года) Дешевле (~1.60 €) Дороже (~5.60 €)
Размер чипа 2.0 × 2.5 мм 2.5 × 2.5 мм
Адрес I2C 0x76 или 0x77
ID датчика 0x58 0x60

ID датчика BMx280 (Chip ID) — уникальный идентификатор модели, который считывается из регистра датчика для проверки его работоспособности.

BMP280: Chip ID = 0x58 (идентифицирует датчик как BMP280)
BME280: Chip ID = 0x60 (идентифицирует датчик как BME280)

Это значение вы не передаете в функцию для начала обмена, а считываете из специального регистра датчика (обычно по адресу 0xD0), чтобы убедиться, что это именно тот датчик, с которым вы работаете.

На многих онлайн-площадках (например, eBay) продавцы часто путают эти датчики и могут отправить BMP280 вместо BME280. Из-за внешней схожести это легко не заметить.

Как отличить визуально:

BME280: чип обычно имеет квадратную форму.
BMP280: чип обычно имеет прямоугольную форму.

Самый надежный способ — прочитать ID устройства через программное обеспечение: у BMP280 это 0x58, а у BME280 — 0x60. Если вы попытаетесь получить показания влажности с BMP280, то он скорее всего вернет `0%` или статичное значение.

[Какой датчик выбрать для своего проекта?]

Выбор зависит от ваших задач:

● Выбирайте BME280, если ваш проект связан с погодой: для создания метеостанции, системы мониторинга теплицы или любого устройства, где влажность воздуха играет ключевую роль, BME280 — это правильный выбор.

● Выбирайте BMP280 для проектов, где важна высота или давление: для барометрического альтиметра в дроне, GPS-навигации или в проектах, где бюджет ограничен и влажность не нужна, BMP280 будет более экономичным решением.

Интересная деталь: хотя оба датчика имеют одинаковую заявленную точность давления (±1 гПа), одно из исследований показало, что BMP280 может быть немного точнее при измерении давления, в то время как BME280 демонстрировал большую погрешность до калибровки.

[Калибровка BME280]

Калибровка датчика BME280 — это процесс получения из его памяти индивидуальных коэффициентов (калибровочных данных) и использования их в специальных формулах для преобразования сырых цифровых сигналов в физические величины — температуру, давление и влажность с высокой точностью [2].

На самом деле, существует два типа калибровки для BME280:

1. Заводская калибровка (обязательная): каждый датчик BME280 уникален. На заводе для него вычисляются индивидуальные коэффициенты, которые учитывают его особенности. Эти коэффициенты хранятся в памяти датчика по адресам от 0x88 до 0xE1 [2, 3]. Ваша задача — прочитать их и применить. Именно это и называется "калибровкой" в технической документации. Без этого вы получите только сырые (и бесполезные) цифровые значения. К счастью, в большинстве готовых библиотек для работы с датчиком этот процесс выполняется автоматически, например, при вызове функции init() [1].

2. Калибровка по точке отсчета (дополнительная): используется, если вы применяете BME280 для определения высоты (альтиметрии). Поскольку давление зависит не только от высоты, но и от погоды, датчику нужно задать "точку отсчета". Это можно сделать, указав текущее давление на уровне моря (из местного прогноза погоды) или точную высоту вашего местоположения (например, по GPS) [4]. Эта калибровка выполняется пользователем в программном обеспечении и не влияет на точность измерения температуры и влажности.

Процесс калибровки (для разработчика). Если посмотреть на процесс изнутри, то калибровка — это считывание и применение калибровочных коэффициентов. Вот как это выглядит в коде:

1. Считайте калибровочные коэффициенты из определенных регистров датчика [1, 2]. Это 24 параметра, каждый из которых может быть 8-, 16- или 32-битным. Для примера, вот как выглядит структура этих коэффициентов из одной из библиотек [1, 5]:

   // Пример структуры калибровочных данных
dig_T1 = 28502, dig_T2 = 26652, dig_T3 = 50 // Коэф. для температуры
dig_P1 = 37088, dig_P2 = -10615, dig_P3 = 3024 // Коэф. для давления
dig_P4 = 8809, dig_P5 = -130, dig_P6 = -7
dig_P7 = 9900, dig_P8 = -10230, dig_P9 = 4285
dig_H1 = 75, dig_H2 = 375, dig_H3 = 0 // Коэф. для влажности
dig_H4 = 289, dig_H5 = 50, dig_H6 = 30

2. Получите сырые данные (ADC) от датчика — это просто числа, например, 51234 для температуры.

3. Примените формулы компенсации, используя сырые данные и считанные коэффициенты. Это довольно сложные математические расчеты (см. GY-BME280-5V-Temperature-and-Humidity-Sensor-1.pdf из архива [7]). Именно они превращают сырые числа в градусы Цельсия, гектопаскали и проценты влажности.

Важное замечание: эти шаги обычно не нужно выполнять вручную. В любом качественном драйвере (для Arduino, ESP-IDF, MicroPython) есть готовая функция, которая делает все это автоматически. Она просто вызывается в начале работы датчика и при каждом чтении данных.

Зачем нужна "калибровка" на практике? Помимо обязательной "математической" калибровки, есть еще один полезный прием — компенсация нагрева от самого микроконтроллера. Если ESP32-C3 (или другая плата) нагревается и расположена рядом с датчиком, это искажает показания температуры. Чтобы это исправить, можно использовать внешнюю температурную калибровку: считывать температуру процессора и вычитать ее влияние из показаний BME280 по специальной формуле [6]. Это повышает точность измерения температуры окружающей среды.

[Ссылки]

1. jupyter_micropython_developer_notebooks/essential_sensor_code/bme280.py.
2. Adafruit BME280 Library, bme280_calib_data Struct Reference.
3. RocketLogger bme280.h.
4. How to Calibrate the Altitude Readings on Bosch BME280 site:manualslib.com.
5. reznikmm / bme280.
6. bme280-python/examples/compensated-temperature.py.
7. 260715BME280doc.zip - документация для датчиков BMP280 и BME280.

 

Добавить комментарий


Защитный код
Обновить

Top of Page