Telegram: Request ESP32/ESP8266 Sensor Readings (Arduino IDE)

This guide shows how to request ESP32 or ESP8266 NodeMCU sensor readings using Telegram. As an example, we’ll request temperature and humidity readings from a BME280 sensor. You just need to send a message to your Telegram Bot to monitor your sensors or inputs from anywhere in the world. The ESP boards will be programmed using Arduino IDE.

ESP32 ESP8266 NodeMCU Send Publish Sensor Readings BME280 Telegram Arduino

Project Overview

In this tutorial we’ll build a simple project that requests ESP32 or ESP8266 NodeMCU temperature and humidity readings using the Telegram app. We’ll use a BME280 sensor, but you can use any other sensor.

ESP32 ESP8266 NodeMCU Telegram Request BME280 Sensor Readings Project Overview
  • You’ll create a Telegram bot for your ESP32 or ESP8266 NodeMCU board;
  • You can start a conversation with the bot;
  • When you send the message /readings to the bot, the ESP board receives the message and responds with the current temperature and humidity readings;
  • You can send the /start message to receive a welcome message with the commands to control the board.

This is a simple project, but shows how you can use Telegram in your IoT and Home Automation projects. The idea is to apply the concepts learned in your own projects.

Introducing Telegram App

Telegram Messenger is a cloud-based instant messaging and voice over IP service. You can easily install it in your smartphone (Android and iPhone) or computer (PC, Mac and Linux). It is free and without any ads. Telegram allows you to create bots that you can interact with.

Bots are third-party applications that run inside Telegram. Users can interact with bots by sending them messages, commands and inline requests. You control your bots using HTTPS requests to Telegram Bot API“.

The ESP32/ESP8266 will interact with the Telegram bot to receive and handle the messages, and send responses. In this tutorial you’ll learn how to use Telegram to send messages to your bot to request sensor readings from anywhere (you just need Telegram and access to the internet).

Creating a Telegram Bot

Go to Google Play or App Store, download and install Telegram.

Install and Download Telegram application to your Android o iOS smartphone

Open Telegram and follow the next steps to create a Telegram Bot. First, search for “botfather” and click the BotFather as shown below. Or open this link t.me/botfather in your smartphone.

botfather

The following window should open and you’ll be prompted to click the start button.

Telegram Start BotFather to Create a new Bot

Type /newbot and follow the instructions to create your bot. Give it a name and username.

Telegram BotFather Create a New Bot

If your bot is successfully created, you’ll receive a message with a link to access the bot and the bot token. Save the bot token because you’ll need it so that the ESP32/ESP8266 can interact with the bot.

Telegram BotFather Get Bot Token

Get Your Telegram User ID

Anyone that knows your bot username can interact with it. To make sure that we ignore messages that are not from our Telegram account (or any authorized users), you can get your Telegram User ID. Then, when your telegram bot receives a message, the ESP can check whether the sender ID corresponds to your User ID and handle the message or ignore it.

In your Telegram account, search for “IDBot” or open this link t.me/myidbot in your smartphone.

Telegram Get Chat ID with IDBot

Start a conversation with that bot and type /getid. You will get a reply back with your user ID. Save that user ID, because you’ll need it later in this tutorial.

Telegram Get Chat ID with IDBot getid

Preparing Arduino IDE

We’ll program the ESP32 and ESP8266 boards using Arduino IDE, so make sure you have them installed in your Arduino IDE.

Universal Telegram Bot Library

To interact with the Telegram bot, we’ll use the Universal Telegram Bot Library created by Brian Lough that provides an easy interface for the Telegram Bot API.

Follow the next steps to install the latest release of the library.

  1. Click here to download the Universal Arduino Telegram Bot library.
  2. Go to Sketch > Include Library > Add.ZIP Library...
  3. Add the library you’ve just downloaded.

Important: don’t install the library through the Arduino Library Manager because it might install a deprecated version.

For all the details about the library, take a look at the Universal Arduino Telegram Bot Library GitHub page.

ArduinoJson Library

You also have to install the ArduinoJson library. Follow the next steps to install the library.

  1. Go to Skech > Include Library > Manage Libraries.
  2. Search for “ArduinoJson”.
  3. Install the library.

We’re using ArduinoJson library version 6.15.2.

Install ArduinoJson Library Arduino IDE

BME280 Sensor Libraries

To get readings from the BME280 sensor module, we’ll use the Adafruit_BME280 library. You also need to install the Adafruit_Sensor library. Follow the next steps to install the libraries in your Arduino IDE:

1. Open your Arduino IDE and go to Sketch Include Library > Manage Libraries. The Library Manager should open.

2. Search for “adafruit bme280 ” on the Search box and install the library.

Installing BME280 library in Arduino IDE

To use the BME280 library, you also need to install the Adafruit Unified Sensor. Follow the next steps to install the library in your Arduino IDE:

3. Search for “Adafruit Unified Sensor“in the search box. Scroll all the way down to find the library and install it.

Installing Adafruit Unified Sensor Driver library

After installing the libraries, restart your Arduino IDE.

Parts Required

For this example we’ll get sensor readings from the BME280 sensor. Here’s a list of parts you need to build the circuit for this project:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic Diagram

The BME280 sensor module we’re using communicates via I2C communication protocol, so you need to connect it to the ESP32 or ESP8266 I2C pins.

BME280 wiring to ESP32

The default ESP32 I2C pins are:

  • GPIO 22SCL (SCK)
  • GPIO 21SDA (SDI)

So, assemble your circuit as shown in the next schematic diagram (Guide for ESP32 with BME280 and ESP32 BME280 Web Server).

ESP32 BME280 Sensor Temperature Humidity Pressure Wiring Diagram Circuit

Recommended reading: ESP32 Pinout Reference Guide

BME280 wiring to ESP8266 NodeMCU

The default ESP8266 I2C pins are:

  • GPIO 5 (D1): SCL (SCK)
  • GPIO 4 (D2): SDA (SDI)

Assemble your circuit as in the next schematic diagram if you’re using an ESP8266 board (Guide for ESP8266 NodeMCU with BME280).

ESP8266 NodeMCU BME280 Sensor Temperature Humidity Pressure Wiring Diagram Circuit

Recommended reading: ESP8266 Pinout Reference Guide

Telegram Request Sensor Readings – Code

The following code allows you to request BME280 sensor readings from your ESP32 or ESP8266 board by sending a message to a Telegram Bot. To make it work for you, you need to insert your network credentials (SSID and password), the Telegram Bot Token and your Telegram User ID.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/telegram-request-esp32-esp8266-nodemcu-sensor-readings/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

  Project created using Brian Lough's Universal Telegram Bot Library: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
*/

#ifdef ESP32
  #include <WiFi.h>
#else
  #include <ESP8266WiFi.h>
#endif
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h> // Universal Telegram Bot Library written by Brian Lough: https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
#include <ArduinoJson.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Use @myidbot to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
#define CHAT_ID "XXXXXXXXXX"

// Initialize Telegram BOT
#define BOTtoken "XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"  // your Bot Token (Get from Botfather)

WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

//Checks for new messages every 1 second.
int botRequestDelay = 1000;
unsigned long lastTimeBotRan;

// BME280 connect to ESP32 I2C (GPIO 21 = SDA, GPIO 22 = SCL)
// BME280 connect to ESP8266 I2C (GPIO 4 = SDA, GPIO 5 = SCL)
Adafruit_BME280 bme;         

// Get BME280 sensor readings and return them as a String variable
String getReadings(){
  float temperature, humidity;
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
  String message = "Temperature: " + String(temperature) + " ºC \n";
  message += "Humidity: " + String (humidity) + " % \n";
  return message;
}

//Handle what happens when you receive new messages
void handleNewMessages(int numNewMessages) {
  Serial.println("handleNewMessages");
  Serial.println(String(numNewMessages));

  for (int i=0; i<numNewMessages; i++) {
    // Chat id of the requester
    String chat_id = String(bot.messages[i].chat_id);
    if (chat_id != CHAT_ID){
      bot.sendMessage(chat_id, "Unauthorized user", "");
      continue;
    }
    
    // Print the received message
    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
    client.setInsecure();
  #endif

  // Init BME280 sensor
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
  
  // Connect to Wi-Fi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }
  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());
}

void loop() {
  if (millis() > lastTimeBotRan + botRequestDelay)  {
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);

    while(numNewMessages) {
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
    lastTimeBotRan = millis();
  }
}

View raw code

The code is compatible with ESP32 and ESP8266 NodeMCU boards. The code will load the right libraries accordingly to the selected board.

How the Code Works

This section explain how the code works. Continue reading or skip to the Demonstration section.

Start by importing the required libraries.

#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>

Network Credentials

Insert your network credentials in the following variables.

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Telegram User ID

Insert your user ID. The one you’ve got from the IDBot.

#define CHAT_ID "XXXXXXXXXX"

Telegram Bot Token

Insert your Telegram Bot token you’ve got from Botfather on the BOTtoken variable.

#define BOTtoken "XXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"  // your Bot Token (Get from Botfather)

Create a new WiFi client with WiFiClientSecure.

WiFiClientSecure client;

Create a bot with the token and client defined earlier.

UniversalTelegramBot bot(BOTtoken, client);

The botRequestDelay and lastTimeBotRan are used to check for new Telegram messages every x number of seconds. In this case, the code will check for new messages every second (1000 milliseconds). You can change that delay time in the botRequestDelay variable.

int botRequestDelay = 1000;
unsigned long lastTimeBotRan;

BME280 Object

Create an Adafruit_BME280 called bme. This creates an I2C object on the default ESP I2C pins.

Adafruit_BME280 bme; 

getReadings()

The getReadings() function requests temperature and humidity from the BME280 sensor and returns the results as a string variable that we can send to the Telegram bot.

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

To learn more about interfacing the BME280 sensor with the ESP32 and ESP8266, read:

handleNewMessages()

The handleNewMessages() function handles what happens when new messages arrive.

void handleNewMessages(int numNewMessages) {
  Serial.println("handleNewMessages");
  Serial.println(String(numNewMessages));

It checks the available messages:

for (int i=0; i<numNewMessages; i++) {

Get the chat ID for that particular message and store it in the chat_id variable. The chat ID identifies who sent the message.

String chat_id = String(bot.messages[i].chat_id);

If the chat_id is different from your chat ID (CHAT_ID), it means that someone (that is not you) has sent a message to your bot. If that’s the case, ignore the message and wait for the next message.

if (chat_id != CHAT_ID){
  bot.sendMessage(chat_id, "Unauthorized user", "");
  continue;
}

Otherwise, it means the message was sent from a valid user. So, we’ll save it in the text variable and check its content.

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

The from_name variable saves the name of the sender.

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

If it receives the /start message, we’ll send the valid commands to control the ESP32/ESP8266. This is useful if you happen to forget what are the commands to control your board.

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

Sending a message to the bot is very simply. You just need to use the sendMessage() method on the bot object and pass as arguments the recipient’s chat ID, the message, and the parse mode.

bool sendMessage(String chat_id, String text, String parse_mode = "")

In our example, we’ll send the message to the ID stored on the chat_id variable (that corresponds to the person who’ve sent the message) and send the message saved on the welcome variable.

bot.sendMessage(chat_id, welcome, "");

If it receives the /readings message, get the current sensor readings by calling the getReadings() function. Then, simply send the message.

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

setup()

In the setup(), initialize the Serial Monitor.

Serial.begin(115200);

If you’re using the ESP8266, you need to use the following line:

#ifdef ESP8266
  client.setInsecure();
#endif

In the Universal Telegram Bot Library library examples for the ESP8266, it says: “This is the simplest way of getting this working. If you are passing sensitive information, or controlling something important, please either use certStore or at least client.setFingerPrint“.

Init BME280

Initialize the BME280 sensor.

if (!bme.begin(0x76)) {
  Serial.println("Could not find a valid BME280 sensor, check wiring!");
  while (1);
}

Init Wi-Fi

Initialize Wi-Fi and connect the ESP to your local network with the SSID and password defined earlier.

WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.println("Connecting to WiFi..");
}

loop()

In the loop(), check for new messages every second.

void loop() {
  if (millis() > lastTimeBotRan + botRequestDelay)  {
    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    while(numNewMessages) {
      Serial.println("got response");
      handleNewMessages(numNewMessages);
      numNewMessages = bot.getUpdates(bot.last_message_received + 1);
    }
    lastTimeBotRan = millis();
  }
}

When a new message arrives, call the handleNewMessages function.

while(numNewMessages) {
  Serial.println("got response");
  handleNewMessages(numNewMessages);
  numNewMessages = bot.getUpdates(bot.last_message_received + 1);
}

That’s pretty much how the code works.

Demonstration

Upload the code to your ESP board, open the Tools menu > Board and select the board you’re using. Go to Tools > Port and select the COM port your board is connected to.

After uploading the code, press the ESP on-board EN/RST button so that it starts running the code. Then, open the Serial Monitor to check what’s happening in the background.

Go to your Telegram account and open a conversation with your bot. Send the following commands and see the bot responding:

  • /start shows the welcome message with the valid commands.
  • /readings returns the current temperature and humidity readings from the BME280 sensor.
Request ESP32 ESP8266 Sensor Readings Telegram Demonstration

At the same time, on the Serial Monitor, you should see that the ESP32 or ESP8266 is receiving the messages.

ESP32 ESP8266 Telegram Request Sensor Readings Serial Monitor

If you try to interact with your bot from another account, you’ll get the the “Unauthorized user” message.

Control ESP32 ESP8266 Outputs Request Sensor Readings Telegram app Unauthorized user

Wrapping Up

In this tutorial you’ve learned how to create a Telegram Bot to interact with the ESP32 or ESP8266 NodeMCU boards. With this bot, you can use your Telegram account to monitor sensors and control outputs.

We’ve shown you a simple example on how to request sensor readings from a BME280 sensor. The idea is to modify the project to add more commands to execute other tasks. For example, you can send a Telegram message to control outputs or send a message to your account when motion is detected.

The great thing about using Telegram to control your ESP boards, is that as long as you have an internet connection (and your boards too), you can control and monitor them from anywhere in the world.

We hope you’ve found this project interesting. Learn more about the ESP32 and ESP8266 with our resources:

Thanks for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

22 thoughts on “Telegram: Request ESP32/ESP8266 Sensor Readings (Arduino IDE)”

  1. Thank you so much Rui and Sara for your great effort in providing great and comprehensive tutorials. We really appreciate your immense effort.

    Reply
  2. I thank both of you, since I was waiting for some project like this for a while… I was managing with RPi but this way we same power and an intermediate.

    Are you going to have this project in micropython also? Thank you.

    Reply
  3. I assume your page has a simple typing error …
    “We’re using ArduinoJson library version 6.5.12.”
    6.5.12 does not exist.
    6.15.2 does, and that’s what is shown on your images

    Reply
  4. Dear Sara, Rui,

    Again a nice tutorial!
    As i1m working with ESP8266 (wemos mini r1d2) modules to aquire data by tcp socket, i really wanted to make this project (to learn advance solutions) . But unfortunately it doesn’t work for me:

    there was no problem with telegram, i could create newbot, get token, get my id etc….
    there was no problem to install telegram library to arduino IDE as you said,
    i couldn’t install arduinoJson by library manager, but i downloaded the ZIP by the link what you shared in the description this is:ArduinoJson VERSION 6.15.1 and i could install it,
    after i upload the program, there was no response to query: /readings or /start, even nothing comes by serial monitor (means: got response or something)
    reason of this i combined your code to my code, so my existing sketch, where my device create a webpage, showing up temp and humidity data. (to ensure there is no network problem)
    my server is:
    WifiServer Server(80), and WiFiClient client = server.available(); ,
    AND your client is:
    WiFiClient client2;
    UniversalTelegramBot bot(BOTtoken, client2); ,

    my server runs OK, (so means network connection ok,) but your code doesn’t response. unfortunately i can not trace where could be wrong, as no such tracing possibilities in the code, what i know the main loop runs every second is OK (I put there a Serial.print to ensure that routine check bot.getupdates every sec.)

    What do you think what else could i check to be able to run?

    Thanks your reply in advance,

    Reply
  5. Your programs don’t work!!! There is no ESP8266wifi library And the telegram bot does not issue an id ! I hope you are checking the code, because it doesn’t work.

    Reply
      • Sorry, I don’t understand why my program didn’t work. The bot didn’t start. It looks like the API was incorrectly specified. You need to repeat the build and programming again.

        Reply
  6. When I search created bot, I found,

    I start it with /start

    No response

    Then I tried, /hetu command

    /getid command not working for me.

    I tried it so many times ,

    Even I delete created bot & create new bot so many times, but failed.

    Could not found my mistake.

    Reply
  7. I tried your esp 8266 temp readings, it is getting compiled but during uploading it shows An error occurred while uploading, pls give your clue to fix this problem.
    S.Yogaraja
    India.

    Reply

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.