Connecting the BME280 sensor to ESP8266 and creating weather station with VizIoT

This article is current as of May 28, 2024, operating system Mac OS.

Introducing BME280 sensor

We went through how to program the ESP8266 module to control the on-board LED as well as remotely access it in the previous block.

This instruction will take us a little further, where we will realize the possibility of creating a home weather station based on a microcontroller ESP8266 and a temperature, humidity and pressure sensor connected to it. For connection we will need the experience from the previous article, BME280 sensor, connecting wires to connect to the pins of the module and the sensor.

View of sensor:
BME280
Side view:
BME280_2
Let's start with physical connection of devices. Connect the ESP8266 module to the computer, similar to the previous article, define the ports and the board. Connect the sensor itself according to the following scheme:

Connection* Плата ESP8266 Датчик BME280
power connection G GND
power connection 3V VCC
control D1 SCL
control D2 SDA


view_esp8266_and_bme280_on_board

Installing the required libraries

Devices are connected, the Adafruit BME280 Library must be installed for the code to work correctly:
Adafruit_BME280_lybrary
You will also need to install the Adafruit Unified Sensor library using the Library Manager in the Arduino IDE:
Adafruit_Sensor_library

I2C address for BME280 sensor

To work with BME280 sensor it is necessary to know its address, as it works on I2C communication protocol, which allows to connect many different sensors with different addresses. Below is provided a sketch to find connected sensors via I2C protocol on pins D1 and D2. Copy, paste, load the following code into the compiler:

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

Open the console (Serial Monitor) to view the address of the sensor connected to the ESP8266 module. The address should be displayed if the connection is made correctly:
I2C_device_address
We can see that the sensor with the address 0x76 is connected. If there is no data in the Serial Monitor, the connection is incorrect, and you will need to troubleshoot the issue. Possible problems include:

  • incorrectly connected pins to the board legs
  • the corresponding port is not selected
  • the appropriate board name is not selected.

Receiving data from the BME280

After the device address is found and the libraries are installed, we can go to file -> examples -> adafruit BME280 Library -> bme280test and install the sketch for BME280 module.
sketch_for_BME280_test
In this sketch we find the parameter Serial.begin(9600); and change the serial baud rate from 9600 to 115200 baud, and in status = bme.begin(); we pass the address we got from the previous scanner sketch. Now it should look like this: 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();
}

then update sketch by pressing upload, open the port monitor where you can see the temperature, humidity, pressure and approximate altitude readings.
serial_monitor_result_of_sketch
To give the pressure reading in millimetres of mercury, go into the original sketch and change 100.0F to 133.33:
change_value_pressure_to_hPa
Reload the sketch and get the answer in the form of our usual indicators:
result_in_hPa

Introduction to VizIoT

In the next section, we will explore the features of the VizIoT website. Why do we need this? In the previous article, we connected the BME280 sensor and saw the temperature, humidity, and atmospheric pressure readings in the console. However, this method of displaying information is inconvenient and impractical. To make it easier to view and analyze the data from our weather station, we will use the VizIoT service. By using VizIoT, we get:

  • access to cloud data storage,
  • tools for data visualization,
  • the ability to share the weather station with friends,
  • notifications in Telegram,
  • and even remote control of our weather station.

This platform is not only useful for home needs but can also be a valuable tool for business or other applications. It can be used to display and process data on:

  • soil temperature and humidity in fields,
  • climatic conditions in greenhouses and farms,
  • resource consumption (electricity, water, gas),
  • the condition of servers and electrical appliances in production facilities, and much more. You can track data using your custom dashboards, analyze information for any period, and manage access to the data. The diagnostics section allows you to analyze all parameters transmitted by devices over a certain period.

The system supports connecting multiple devices through MQTT and HTTP protocols. Future plans for VizIoT include expanding its capabilities, adding support for the LoRaWAN protocol, and creating new widgets such as weather, manipulators (switch buttons, sliders), and audio/video players. Functionality for processing geographic data will also be added, for example, displaying GPS data points and sensor movement tracks.

Sending Data from BME280 to the VizIoT Server

We previously covered how to connect the BME280 sensor to the ESP8266. Now, let's move on to the next stage, where the connected sensor will transmit temperature and humidity readings to a remote server, from which we will display the parameters on the screen. To do this, we need to visit the VizIoT website, register, and obtain a key and password for the device.

On the "devices" page, create a new device named ESP8266+BME280 (the name is optional), and then obtain the access key and password for this device.
add_new_device_weather_station_en
The key and password obtained earlier will be used in the following sketch, which can be copied and pasted into Arduino IDE:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_BME280.h>                         // Connecting the library Adafruit_BME280

HTTPClient http;
WiFiClient client;

Adafruit_BME280 bme;                   // Setting interface communication I2C 
//ssid and WI-FI password
const char* ssid = "name_your_ssid";
const char* password = "97!_gfd111";

const char* host = "VizIoT.com";
const int port = 48656;

//Key and pass to VizIoT
String VizIoT_Device_key = "9CPJ9RSTYTOI4GK1";
String VizIoT_Device_pass = "XG4WB1GZBJDAG2K313QM";

void setup() {
  //Switching on the information output Serial Monitor
  Serial.begin(115200);
bool status;
  //connection to WI-FI
  setup_wifi();

  Serial.println("Sensor search BME280");
  if (!bme.begin(0x76)) {                 // sensor initialisation
    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("Temperature *C = ");
    Serial.println(t);
    url += String("&temp.=") + t;
  } else {
    Serial.println("Error reading temperature");
  }

  if (! isnan(h)) {
    Serial.print("Hum.(RH) % = ");
    Serial.println(h);
    url += String("&Hum.(RH)=") + h;
  } else {
    Serial.println("Error in reading humidity");
  }

  if (sendGetRequest(url) == true) {
    Serial.println("Data successfully sent to the server");
  } else {
    Serial.println("An error occurred while sending data");
  }

  delay(20000);
}

void setup_wifi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    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;
  }
}

After installing the sketch on the ESP8266 module, the following information should appear in the console (Serial Monitor):
serial_monitor_send_data_by_http_en
In the screenshot above we can see that BME280 is successfully connected to ESP8266 board and transmits data to VizIoT server. If there is no data transmission and errors are detected in the console, make sure that you have correctly entered the password and name of the Wi-Fi network, as well as the device key and password from the VizIoT website, and also make sure that the BME280 sensor is communicating with the I2C interface.

Next, on the VizIoT website, open the "Dashboard" tab and create a panel called "Temperature and Humidity ":
temp_humidity_panel_en
In the "Form add widget" add a widget, name it "Temperature", set parameters - type: "Chart", select device, parameters for visualization Temp.:
create_widjet_temperature_en
Also in the "Form add widget" add a widget, name it "Humidity", set parameters - type: "Chart", select device, parameters for visualization *Hum. (RH):
create_widjet_hum_en
The third widget will be titled “Temp. and Humidity”. Here, we will specify the following parameters: widget type - "Bar chart changes in 1 hour", device selection, and parameters for visualizing - Temperature (temp.) and Humidity (RH).
temp_hum_gisto_en
As a result, you should see the following three widgets on the screen, each displaying graphs depicting the temperature and humidity readings from the BME280 weather sensor:


added_panel_hum_temp_en