Telegram ESP32/ESP8266: Display BME280 sensor readings using Arduino IDE

In a previous tutorial, we learned how to control the output of our ESP32 or ESP8266 NodeMCU by using Telegram Bot (Telegram ESP32 and ESP8266: Control GPIOs and LEDs using Arduino IDE). This time we will take our project further and use telegram to request sensor readings from the ESP32/ESP8266 board. We will create a telegram bot that will display the sensor readings to the user whenever they will be requested. Any appropriate sensor can be used but for this article, we will use a BME280 sensor which is used to measure temperature, pressure, and humidity.

Telegram ESP32 and ESP8266 Display BME280 sensor readings using Arduino IDE

What is Telegram?

Telegram is free of cost messaging application which allows users to send messages and make voice/video calls. For the user, it becomes extremely interactive as well as easy to use this application to control any AC appliance from anywhere over the internet. Only the Telegram application and a steady internet connection in your device (smartphone, laptop, tablet, etc.) is a requirement. It is available for different operating systems including Windows, macOS, Linux, Android, and Apple iOS. Additionally, it also has the feature for third-party developers to create bots.

These bots are set up without much hassle and can execute commands through cross texting. They can also be invited into different groups and can be interfaced with any software program to trigger an event. We will use our ESP32 or ESP8266 module to interact with the bot. This will in return receive and handle the messages and send appropriate responses to the user.

ESP32/ESP8266 with BME280 Telegram Project Overview

We will use Telegram to request the sensor readings from BME280 which will be connected to the ESP32 or ESP8266 development board.

  • Firstly, we will install the Telegram application on our smartphone and then create a Telegram Bot for our ESP board.
  • Secondly, we will use the bot token to start communicating with it. Type /start to receive the welcome message.
  • Then as we want to access the sensor readings, we will send a message (/readings) to the bot. Hence, the bot will receive the message and display the current temperature, humidity and pressure readings.

Installing Telegram on your device

We will use an Android smartphone for this project. So go to Google Play or Apple Store (if using an iPhone).

Telegram_ESP32_ESP8266_GooglePlayIcon_AppStoreIcon
Google Play (Android) and App Store (iPhone) Icons

Search for ‘Telegram’ and install the application.

Telegram_ESP32_ESP8266_APP

When the installation is finished open the application. You will get to view the Start Messaging button. Click it.

Telegram_ESP32_ESP8266_startmessaging

As you will be using this application for the first time a Sign Up is necessary. Complete the sign up by giving in your smartphone number and country code as shown below.

Telegram_ESP32_ESP8266_signup

Creating Telegram Bot

Open the Telegram app after you have successfully signed up. In the search option type ‘BotFather’.

Telegram_ESP32_ESP8266_search

Choose the one with the verified blue tick as shown in the picture below.

Telegram_ESP32_ESP8266_botfather

The following window will open up. Click the ‘Start’ button to proceed forward.

Telegram_ESP32_ESP8266_botfather_start

Now, type /newbot and send the message to the bot. This will create a new bot for us which we will use in our project.

Telegram_ESP32_ESP8266_botfather_newbot

Next, we will choose a name and username for our bot. You can type any name which you want. For the username you will have to try multiple names until an un-used valid name is chosen. Keep your username safe with you as your bot can be accessed through it.

elegram_ESP32_ESP8266_botfather_newbot_NAME

You will receive a Congratulations message after your username gets accepted. Inside that message, there will be a link through which you will be able to access your bot. Additionally, there will also be a bot token. This bot token will be used for the interaction between the ESP32/ESP8266 board and the Telegram bot.

Telegram_ESP32_ESP8266_botfather_newbot_NAME_USERNAME

Telegram User ID

Now, we will set up our Telegram user ID. This will be of immense help as it will filter out all unnecessary messages which we did not send or were not sent by an authorized user. This user id will be unique to a user and will help the ESP module to distinguish whether the message was sent by us or by someone else who was able to access our bot.

Open your Telegram app and go to the search tab. Write ‘IDBot’ and press enter.

Telegram_ESP32_ESP8266_botfather_idbot

The following window will open up. Send /getid command and you will receive your telegram user ID.

Telegram_ESP32_ESP8266_botfather_idbot_telegramuserID

Introduction to BME280 sensor

The BME280 sensor is used to measure readings regarding ambient temperature, barometric pressure, and relative humidity. It is mostly used in web and mobile applications where low power consumption is key. This sensor uses I2C or SPI to communicate data with the micro-controllers. Although there are several different versions of BME280 available in the market, the one we will be studying uses the I2C communication protocol and SPI.

Connecting BME280 sensor with the ESP32/ESP8266 development board

The connection of BME280 with the ESP boards is very easy. We have to connect the VCC terminal with 3.3V, ground with the ground (common ground), SCL of the sensor with SCL of the module, and SDA of the sensor with the SDA pin of the ESP modules.

The I2C pin in ESP32 for SDA is GPIO21 and for SCL is GPIO22
For ESP8266 the default I2C pins for SDA are GPIO4 and for SCL are GPIO5

Required Components

We will need the following components to connect our ESP32 board with the BME280 sensor.

  1. ESP32 or ESP8266 board
  2. BME280 Sensor
  3. Connecting Wires
  4. Breadboard

Schematic Diagram

Follow the schematic diagrams below for both the ESP modules and connect them accordingly. If you are using ESP32 for this project, connect the ESP32 device with BME280 as shown in the schematic diagram below:

BME280 with ESP32 MicroPython
Connection diagram of ESP32 and BME280

Similarly, you are using ESP8266 NodeMCU for this project, connect the ESP8266 device with BME280 as shown in the schematic diagram below:

BME280 with ESP8266 MicroPython
Connection diagram of ESP8266 and BME280

In some BME280 sensors as seen in the above connection diagram, the SCK terminal means the SCL pin and is connected with its respective GPIO pin on the ESP board. Likewise, the SDI terminal means the SDA pin and is connected with its respective GPIO pin on the board. Vin is connected with a 3.3V pin on the module and both the ESP board and the sensor is commonly grounded.

Setting up Arduino IDE

Before we proceed further, you should make sure that you have the latest version of Arduino IDE installed on your system. Moreover, you should also install an ESP32 add-on or an ESP8266 add-on in Arduino IDE. f your IDE does not have the plugins installed you can visit the links below:

Installing ESP32 library in Arduino IDE and upload code
Installing ESP8266 library in Arduino IDE

For this project, we will have to install libraries for the BME280 sensor, Telegram bot and Arduino JSON.

Installing Universal Telegram Bot Library

The Universal Telegram Bot library can be accessed by clicking here. Open this webpage and download the zip file highlighted in the red rectangular box. This library will help us in interacting with the telegram bot and providing us with a straightforward API.

After you have downloaded the .zip file, open your Arduino IDE. Go to Sketch > Include Library > Add .zip Library to add the library. After installation of the library, restart your IDE. We will not install the library from the Arduino Library Manager due to possible conflicting older versions.

Telegram_ESP32_ESP8266_Installing_UniversalTelegramBot_library
Installing Universal Telegram Bot library

Installing ArduinoJson Library

To install the ArduinoJson library, open the IDE and go to Sketch > Include Library > Manage Libraries. Type ‘ArduinoJson’ in the search tab and press enter. Install the library that is highlighted in the red rectangular box.

Telegram_ESP32_ESP8266_Installing_ArduinoJson_library
Installing ArduinoJson library

Installing BME280 Libraries

As we are connecting the BME280 sensor with ESP32/ESP8266 so we will have to install BME280 libraries to our module. We will require two libraries for this project:

  1. Adafruit_BME280 library
  2. Adafruit_Sensor library

We will use the Library Manager in our Arduino IDE to install the latest versions of the libraries. Open your Arduino IDE and go to Sketch > Include Libraries > Manage Libraries. Type each library name in the search bar and install them both.

Adafruit BME280 library Arduino IDE
Adafruit unified sensor library install

Arduino Sketch

Open your Arduino IDE and go to File > New to open a new file. Copy the code given below in that file. This code will work for both ESP32 and ESP8266 development boards. You just have to replace the network credentials, bot token and telegram user ID with your values.

#ifdef ESP32
  #include <WiFi.h>
#else
  #include <ESP8266WiFi.h>
#endif
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h> 
#include <ArduinoJson.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>

const char* ssid = "Your_SSID";  //Write your SSID
const char* password = "Your_Password";  //Write your Password

#define CHAT_ID  "**********"   //Replace with your Telegram User ID
#define BOTtoken "**********:***********************************"  // Replace this with your Bot Token

#ifdef ESP8266
  X509List cert(TELEGRAM_CERTIFICATE_ROOT);
#endif

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

int Delay = 1000;
unsigned long last_time;

Adafruit_BME280 bme;         

String getReadings(){
  float temperature, humidity, pressure;
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
 
  String message = "Temperature: " + String(temperature) + " ºC \n";
  message += "Humidity: " + String (humidity) + " % \n";
    message += "Pressure: " + String (pressure) + " hPa \n";
  return message;
}

void Handle_messages(int new_messages) {
  Serial.println("Handling New Messages ");
  Serial.println(String(new_messages));

  for (int i=0; i<new_messages; i++) {
    String chat_id = String(bot.messages[i].chat_id);
    if (chat_id != CHAT_ID){
      bot.sendMessage(chat_id, "Unauthorized user", "");
      continue;
    }
    
    String text = bot.messages[i].text;
    Serial.println(text);

    String from_name = bot.messages[i].from_name;

    if (text == "/start") {
      String welcome = "Welcome, " + from_name + ".\n";
      welcome += "Use the following command to get current readings.\n\n";
      welcome += "/readings \n";
      bot.sendMessage(chat_id, welcome, "");
    }

    if (text == "/readings") {
      String readings = getReadings();
      bot.sendMessage(chat_id, readings, "");
    }  
  }
}

void setup() {
  Serial.begin(115200);

  #ifdef ESP8266
    configTime(0, 0, "pool.ntp.org");      
    client.setTrustAnchors(&cert); 
  #endif
  
  if (!bme.begin(0x76)) {
    Serial.println("BME280 not connected properly. Check circuit!");
    while (1);
  }
  
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  #ifdef ESP32
    client.setCACert(TELEGRAM_CERTIFICATE_ROOT); 
  #endif
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println(WiFi.localIP());
}

void loop() {
  if (millis() > last_time + Delay)  {
    int new_messages = bot.getUpdates(bot.last_message_received + 1);

    while(new_messages) {
      Serial.println("Got response");
     Handle_messages(new_messages);
      new_messages = bot.getUpdates(bot.last_message_received + 1);
    }
    last_time = millis();
  }
}

How the Code Works?

Including Libraries

We will start by including all the necessary header files which are required for ESP32 and ESP8266 to send and receive notifications from telegram. As this code is compatible with both ESP32 and ESP8266, therefore, both libraries WiFi.h and ESP8266WiFi.h) are defined. As a result, this library will help in establishing the connection between our ESP modules to a wireless network. We will also include the other libraries which we installed previously, the Universal Telegram Bot library, ArduinoJson library, Adafruit BME280 library and Adafruit Unified Sensor library.

#ifdef ESP32
  #include <WiFi.h>
#else
  #include <ESP8266WiFi.h>
#endif
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h> 
#include <ArduinoJson.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>

Setting Network Credentials

Next, we will create two global variables, one for the SSID and the other for the password. These will hold our network credentials which will be used to connect to our wireless network. Replace both of them with your credentials to ensure a successful connection.

const char* ssid = "Your_SSID";  //Write your SSID
const char* password = "Your_Password";  //Write your Password

Specifying Bot Token and Telegram User ID

Next up is a very important step. You will have to specify your bot token to establish a successful connection between the ESP board and the telegram bot. To access your bot token, open your Telegram application and go to BotFather. You will be able to view your bot token in the congratulatory message there. Copy it carefully in the program code. Next, to distinguish unauthorized users we will also add our Telegram user ID. You can access it through the IDBot. We have defined it as ‘CHAT_ID.’

#define CHAT_ID  "**********"   //Replace with your Telegram User ID
#define BOTtoken "**********:***********************************"  // Replace this with your Bot Token

Creating WIFI Client

Then we will create a new WiFi client of the WiFiClientSecure library. By specifying the bot token and the new client which we created before, we will create a new bot by accessing the Universal Telegram Bot library. The bot_delay variable will check for new messages after a specified number of milliseconds. We have specified 1000 milliseconds which means that after every second the ESP board will check for any new message received.

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

Adding Delay

The Delay variable will check for new messages after a specified number of milliseconds. We have specified 1000 milliseconds. As a result, after every second the ESP board will check for any new message received.

int Delay = 1000;
unsigned long last_time;

Creating BME280 Object

Additionally, we will also create an object of Adafruit_BME280 called ‘bme’ which we will use later on to initialize the sensor.

Adafruit_BME280 bme;

getReadings() function

Inside the getReadings() function, we will first define three variables of type float which will hold the sensor values. Then, we will use the bme object on readTemperature(), readHumidity() and readPressure() to access the readings individually. These sensor readings will be saved in the variables which we defined above: temperature, humidity and pressure.

This function will return a string variable ‘message’ with all the three sensor readings which the ESP board will transmit to the Telegram Bot.

String getReadings(){
  float temperature, humidity, pressure;
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
 
  String message = "Temperature: " + String(temperature) + " ºC \n";
  message += "Humidity: " + String (humidity) + " % \n";
    message += "Pressure: " + String (pressure) + " hPa \n";
  return message;
}

Handle_messages() function

The Handle_messages() function takes in a single parameter ‘new_messages.’ Whenever a new message will be sent by the user to the telegram bot a text will display on the serial monitor. It will specify ‘Handling New Messages’ and the number of new messages received.

Serial.println("Handling New Messages ");
Serial.println(String(new_messages));

For every message that is received its chat id (Telegram user ID) gets saved in the variable chat_id. The function then checks through a for loop whether this id matches with the user chat id which was initially defined in the code. If both the ids do not match it means an unauthorized user sent the message. Thus, the bot will specify to us that it was an unauthorized user through bot.sendMessage() and will move onto the next message instead. If both the chat ids match then it means that the rightful user sent the message and it will get saved in the variable ‘text.’

for (int i=0; i<new_messages; i++) {
    String chat_id = String(bot.messages[i].chat_id);
    if (chat_id != CHAT_ID){
      bot.sendMessage(chat_id, "Unauthorized user", "");
      continue;
    }

The message sent by the valid user will get saved in the variable text. It will then get printed on our serial monitor. Moreover, we will also save the name of the sender in the variable from_name. This will be used later to display the Welcome message.

    String text = bot.messages[i].text;
    Serial.println(text);
    String from_name = bot.messages[i].from_name; 

Commands Execution

Now we will define and handle the different commands which we will send to our telegram bot. We will be sending in a total of four commands: /start and /readings.

Firstly, if we send the /start command to the bot and a Welcome message will be displayed to us. We will receive a message displaying the command we can use to access the sensor readings. This will be accomplished by using the sendMessage() method on the bot object like this: bot.sendMessage(). The chat id, the Welcome text and an empty string will be passed as parameters inside it. In our case: bot.sendMessage(chat_id, welcome, “”)

    if (text == "/start") {
      String welcome = "Welcome, " + from_name + ".\n";
      welcome += "Use the following command to get current readings.\n\n";
      welcome += "/readings \n";
      bot.sendMessage(chat_id, welcome, "");
    }

Secondly, if we send the /readings message then all the three current sensor readings will be displayed. This will occur by calling the getReadings() function.

    if (text == "/readings") {
      String readings = getReadings();
      bot.sendMessage(chat_id, readings, "");
    }  
  }
} 

Setup()

Inside the setup() function, we will start the serial connection at a baud rate of 115200.

Serial.begin(115200);

For ESP8266 some additional lines of code will also be added as shown below:

#ifdef ESP8266
    configTime(0, 0, "pool.ntp.org");      // get UTC time via NTP
    client.setTrustAnchors(&cert); // Add root certificate for api.telegram.org
  #endif

Then we will initialize the BME280 sensor. If the connection between the module and the sensor is incorrect it will print that message on the serial monitor.

if (!bme.begin(0x76)) {
    Serial.println("BME280 not connected properly. Check circuit!");
    while (1);
  }

The following section of code will connect our ESP32/ESP8266 board with the local network whose network credentials we already specified above. After the connection will be established, the IP address of the ESP32 board will get printed on the serial monitor.

WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  #ifdef ESP32
    client.setCACert(TELEGRAM_CERTIFICATE_ROOT); 
  #endif
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println(WiFi.localIP());
}

loop()

Inside the loop() function new messages will be checked after every second and saved in the variable ‘new_messages.’. Whenever a new message will be received the Handle_messages() function will be called with the message as a parameter.

void loop() {
  if (millis() > last_time + Delay)  {
    int new_messages = bot.getUpdates(bot.last_message_received + 1);
    while(new_messages) {
      Serial.println("Got response");
     Handle_messages(new_messages);
      new_messages = bot.getUpdates(bot.last_message_received + 1);
    }
    last_time = millis();
  }
}

Demonstration

Make sure you choose the correct board and COM port before uploading your code to the board. Therefore go to Tools > Board and select ESP32 Dev Module or ESP8266 Module.

If you are using ESP32, select the ESP32 Dev module as follows:

select esp32 board
Choosing Board

If you are using ESP8266 NodeMCU, select the NodMCU module as follows:

selecting ESP8266 NodeMCU in Arduino IDE

Then, go to Tools > Port and select the appropriate port through which your board is connected.

Selecting COM PORT ESP32
Choosing COM Port

Click on the upload button to upload the code to ESP32 or ESP8266 development board.

After you have uploaded your code to the ESP32 or ESP8266 development board, press its ENABLE button.

ESP32 enable reset button
Press ENABLE button

ESP8266 NodeMCU reset button:

ESP8266 NodeMCU reset button

In your Arduino IDE, open up the serial monitor and you will see that the IP address will be assigned to your ESP32/ESP8266 board.

Telegram with BME280 demo serial monitor
Serial Monitor

Now open your Telegram application on your smartphone. Go to BotFather and access the bot you created by following the link provided there as follows:

Type /start and press enter to send it to your newly created bot. As a result, this will show you a welcome message from the bot. All the different commands will be displayed which you can enter one by one.

Now send /readings command to get sensor readings on telegram application.

The bot will respond to the command accordingly by displaying the sensor readings. The serial monitor will also continuously give updates after each command is executed.

Conclusion

In conclusion, we learned how to request ESP32/ESP8266 sensor readings via the Telegram Bot. Through Telegram it is very convenient to control any home appliances, relay, etc, from anywhere in the world. We can also use Telegram bots to control GPIOs of the ESP modules, get pictures from ESP32-CAM, and for many other applications.

You may also like to read these:

Leave a Comment