Подключение датчика BME280 к ESP8266 и создание метеостанции с помощью VizIoT

алгоритм актуален на 24.04.2024, операционная система Mac OS.

Подключение датчика BME280 к ESP8266

Как программировать модуль ESP8266 для управления встроенным на плате светодиодом, а также удаленный доступ к нему, мы проходили в предыдущем блоке.

Данная инструкция продвинет нас несколько дальше, где мы реализуем возможность создания домашней метеостанции на базе микроконтроллера ESP8266 и подключенного к нему датчика температуры, влажности и давления. Для подключения нам понадобится опыт с предыдущей статьи, датчик BME280, соединительные провода для подключения к ногам модуля и датчика.

Вид датчика:
BME280
Вид сбоку:
BME280_2
Начнем с физического подключения устройств. Модуль ESP8266 подключаем к компьютеру, аналогично предыдущей статье, определяем порты и плату. Сам датчик подключаем по следующей схеме:

Подключение* Плата ESP8266 Датчик BME280
питание G GND
питание 3V VCC
управление D1 SCL
управление D2 SDA


view_esp8266_and_bme280_on_board

Установка необходимых библиотек

Устройства подключены, теперь для корректной работы sketch необходимо установить библиотеку Adafruit BME280 Library:
Adafruit_BME280_lybrary
А также библиотеку Adafruit Unified Sensor через Library Manager в Arduino IDE:
Adafruit_Sensor_library

Как узнать I2C адрес датчика BME280

Также для работы с датчиком BME280 необходимо узнать его адрес, так как он работает по I2C шине, которая позволяет подключать на нее множество различных датчиков, но с разными адресами. Ниже предоставлен скетч для поиска подключенных датчиков к шине I2C на контактах D1 и D2. Копируем, вставляем, загружаем в компилятор следующий код:

#include <Wire.h>

void setup(){
    Wire.begin(D2,D1);
    Serial.begin(115200);
    while (!Serial);
    Serial.println("\nI2C Scanner");
} 

void loop(){
    byte error, address;
    int nDevices;

    Serial.println("Scanning...");

    nDevices = 0;
    for(address = 8; address < 127; address++ ){
        Wire.beginTransmission(address);
        error = Wire.endTransmission();

        if (error == 0){
            Serial.print("I2C device found at address 0x");
            if (address<16)
                Serial.print("0");
            Serial.print(address,HEX);
            Serial.println(" !");

            nDevices++;
        }
        else if (error==4) {
            Serial.print("Unknow error at address 0x");
            if (address<16)
                Serial.print("0");
            Serial.println(address,HEX);
        } 
    }
    if (nDevices == 0)
        Serial.println("No I2C devices found\n");
    else
        Serial.println("done\n");

    delay(5000);
}

Открываем «монитор порта» (Serial monitor), где при правильном подключении должен появиться адрес датчика, который подключен к модулю ESP8266:
I2C_device_address
И видим, что подключен один датчик с адресом 0x76. Так как мы подключили только один датчик к шине I2C значит адрес BME280 = 0x76. Если в «монитор порта» нет данных, то соответственно подключение некорректно, нужно искать причину. Из возможных неполадок:

  • неправильно подключены контакты к ногам платы
  • не выбран соответствующий порт
  • не выбрано соответствующее название платы.

Получение данных от BME280

После того как адрес устройства найден и библиотеки установлены, можем зайти в file -> examples -> adafruit BME280 Library -> bme280test и установить скетч для модуля BME280.
sketch_for_BME280_test
В данном скетче находим параметр Serial.begin(9600); и меняем скорость последовательной связи с 9600 на 115200 baud, а также в status = bme.begin(); передаем адрес, который мы получили с предыдущего скетча-сканера. Теперь он должен выглядеть так: status = bme.begin(0x76);

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#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(115200); 
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));

    unsigned status;

    // default settings
    status = bme.begin(0x76);  
    // You can also pass in a Wire library object like &Wire2
    // status = bme.begin(0x76, &Wire2)
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }

    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");

    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();
}

после чего прошиваем плату нажатием upload, открываем монитор порта, где видим показатели температуры, влажности, давления и приблизительной высоты.
serial_monitor_result_of_sketch
Чтобы привести показатель давления в миллиметрах ртутного столба, заходим в исходный sketch и меняем 100.0F на 133.33
change_value_pressure_to_hPa
Перезаливаем скетч и получаем ответ в виде обычных для нас показателях
result_in_hPa

Знакомство с VizIoT

В следующем разделе мы рассмотрим возможности сайта VizIoT. Зачем нам это нужно? В предыдущей статье мы подключили датчик BME280 и видели показания температуры, влажности и атмосферного давления в консоли. Однако такой способ отображения информации неудобен и не практичен. Чтобы было удобнее просматривать и анализировать данные нашей метеостанции, мы воспользуемся сервисом VizIoT. Используя VizIoT, мы получаем:

  • доступ к облачному хранилищу данных,
  • инструменты для визуализации данных,
  • возможность поделиться метеостанцией с друзьями,
  • уведомления в Telegram,
  • и даже возможность удаленного управления нашей метеостанцией.

Эта платформа не только удовлетворяет домашние потребности, но также может быть полезным инструментом для бизнеса или других процессов. Она может использоваться для отображения и обработки данные о:

  • температуре и влажности почвы на полях,
  • климатических условиях в теплицах и фермах,
  • расходе ресурсов (электроэнергии, воды, газа),
  • состоянии серверов и электроприборов в производственных помещениях и многое другое.

Вы можете отслеживать данные с помощью созданных вами панелей, анализировать информацию за любой период и управлять доступом к данным. Раздел диагностики позволяет анализировать все параметры, переданные приборами за определенный период времени.

Система поддерживает подключение множества устройств через протоколы MQTT и HTTP. В будущем планируется расширение возможностей VizIoT, включая добавление поддержки протокола LoRaWAN и создание новых виджетов, таких как: погода, манипуляторы (кнопки переключатели, слайдеры) и аудио/видео плеер. Также будет добавлен функционал обработки географических данных, например, отображение GPS точек сбора данных и треков передвижения датчиков.

Передача данных с BME280 на сервер VizIoT

Как подключить датчик BME280 к ESP8266 мы проходили выше, теперь перейдем к следующему этапу, где подключенный датчик будет передавать показатели температуры и влажности на удаленный сервер, с которого выведем параметры на экран. Для этого нам понадобится зайти на сайт VizIoT, зарегистрироваться и получить ключ и пароль устройства. На странице «устройства» создаем новое устройство с названием ESP8266+BME280 (название опциональное), после чего получаем ключ доступа и пароль к этому устройству.
add_new_device_weather_station

Полученные данные (ключ и пароль) будем использовать в следующем скетче, который можно скопировать и вставить в Arduino IDE:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_BME280.h>                            // Подключаем библиотеку Adafruit_BME280

HTTPClient http;
WiFiClient client;

Adafruit_BME280 bme;                                    // Установка связи по интерфейсу I2C 
//ssid и пароль доступа для подключения к WI-FI
const char* ssid = "xxxx";
const char* password = "xxxx";

//Адрес и Порт сервера
const char* host = "VizIoT.com";
const int port = 48656;

//Ключ и пароль доступа VizIoT Устройства (можно узнать в настройках устройства)
String VizIoT_Device_key = "xxxx";
String VizIoT_Device_pass = "xxxx";

void setup() {
  //Включаем вывод информации в Serial Monitor
  Serial.begin(115200);
bool status;
  //Подключаемся к WI-FI
  setup_wifi();

  Serial.println("Поиск датчика BME280");
  if (!bme.begin(0x76)) {                               // Проверка инициализации датчика
    Serial.println("Could not find a valid BME280 sensor, check wiring!"); // Печать, об ошибки инициализации.
    while (1);                                          // Зацикливаем
  }
}


void loop() {

  String url = String("/update?key=") + VizIoT_Device_key + "&" + "pass=" + VizIoT_Device_pass ;

  //считываем показания с датчиков
  float t = bme.readTemperature();
  float h = bme.readHumidity();

  //проверяем информацию о температуре
  if (! isnan(t)) {
    Serial.print("Температура *C = ");
    Serial.println(t);
    url += String("&temp.=") + t;
  } else {
    Serial.println("Ошибка при чтении температуры");
  }

  //проверяем информацию о влажности
  if (! isnan(h)) {
    Serial.print("Hum.(RH) % = ");
    Serial.println(h);
    url += String("&Hum.(RH)=") + h;
  } else {
    Serial.println("Ошибка при чтении влажности");
  }

  if (sendGetRequest(url) == true) {
    Serial.println("Данные успешно отправлены на сервер");
  } else {
    Serial.println("Во время отправки данных возникла ошибка");
  }

  //уснуть на 20 секунд
  delay(20000);
}

//Функция подключения к WI-FI
void setup_wifi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    //Ожидает подключения к WI-FI
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
}

//Функция отправки данных на сервер
int sendGetRequest(String url) {
  if (WiFi.status() == WL_CONNECTED) {
    http.begin(client, host, port, url);
    int httpCode = http.GET();
    if (httpCode > 0) {
      String payload = http.getString();
      http.end();
      if (payload.equals("OK")) {
        return true;
      } else {
        return false;
      }
    } else {
      Serial.println("[HTTP] GET... failed, error!!!\r\n");
      Serial.print("httpCode = ");
      Serial.println(httpCode);
      http.end();
      return false;
    }
  } else {
    return false;
  }
}

После установки скетча на модуль ESP8266, в консоли (монитор порта) должна появиться следующая информация:
serial_monitor_send_data_by_http
На скриншоте выше мы видим, что BME280 успешно подключен к плате ESP8266 и передает данные на сервер VizIoT. В случае отсутствия передачи данных и обнаружения ошибок в консоли, нужно убедиться, что вы правильно ввели пароль и название сети Wi-Fi, а также ключа и пароля устройства с сайта VizIoT, также нужно убедиться, что с датчиком BME280 установлена связь по и интерфейсу I2C (ай ту си).

Следующим шагом на сайте VizIoT, открываем вкладку "Панели" и создаем панель с названием "темп. и влажность":
temp_humidity_panel
В созданной панели добавляем виджет, называем "Температура", устанавливаем параметры - тип: «График», выбираем устройство, параметры для визуализации Temp.:
create_widjet_temperature
Также добавляем виджет "Влажность", указываем параметры: тип: «График», выбираем устройство, параметры для визуализации Hum. (RH):
create_widjet_hum
Третий виджет назовем "Темп. и влага". Здесь мы укажем следующие параметры: тип виджета - «Гистограмма изменений за 1 час», выбираем устройство, параметры для визуализации - Температура Temp. и Влажность Hum. (RH):
temp_hum_gisto
В итоге на экране должны появиться следующие 3 виджета с графиками, на которых можно наблюдать за температурой и влажностью, получаемых с метео-датчика BME280:
added_panel_hum_temp