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.
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).
Search for ‘Telegram’ and install the application.
When the installation is finished open the application. You will get to view the Start Messaging button. Click it.
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.
Creating Telegram Bot
Open the Telegram app after you have successfully signed up. In the search option type ‘BotFather’.
Choose the one with the verified blue tick as shown in the picture below.
The following window will open up. Click the ‘Start’ button to proceed forward.
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.
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.
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 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.
The following window will open up. Send /getid command and you will receive your telegram user ID.
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.
- ESP32 or ESP8266 board
- BME280 Sensor
- Connecting Wires
- 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:
Similarly, you are using ESP8266 NodeMCU for this project, connect the ESP8266 device with BME280 as shown in the schematic diagram below:
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.
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.
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:
- Adafruit_BME280 library
- 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.
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:
If you are using ESP8266 NodeMCU, select the NodMCU module as follows:
Then, go to Tools > Port and select the appropriate port through which your board is connected.
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.
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.
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:
Hello
Telegram is blocked in my area and i am using mtproto proxy on my mobile telegram app to access telegram server. I interest to use your code in this tutorial, Would you please guide me how to use Telegram mtproto proxy in Arduino Sketch?