{"id":2120,"date":"2023-04-20T11:41:04","date_gmt":"2023-04-20T09:41:04","guid":{"rendered":"https:\/\/www.sabulo.com\/sb\/?p=2120"},"modified":"2023-04-20T11:43:44","modified_gmt":"2023-04-20T09:43:44","slug":"restarting-an-esp32-via-telegram","status":"publish","type":"post","link":"https:\/\/www.sabulo.com\/sb\/esp32-development-board\/restarting-an-esp32-via-telegram\/","title":{"rendered":"Restarting an ESP32 via Telegram"},"content":{"rendered":"\n<p>Whoops, quite a long time with no posts! <\/p>\n\n\n\n<p>Apologies for that, but it&#8217;s been a busier-than-usual year at <a href=\"http:\/\/www.haaga-helia.fi\/en\" target=\"_blank\" rel=\"noreferrer noopener\">Haaga-Helia UAS<\/a> and especially the <strong><a href=\"http:\/\/www.hh3dlab.fi\/\" target=\"_blank\" rel=\"noreferrer noopener\">Haaga-Helia 3D + Robo Lab<\/a><\/strong>.<\/p>\n\n\n\n<p>Speaking of which, there is a new system in place where the lab status can be seen online. The user interface looks like this:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/Capture2.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/Capture2.jpg?resize=484%2C463&#038;ssl=1\" alt=\"\" class=\"wp-image-2121\" width=\"484\" height=\"463\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/Capture2.jpg?w=484&amp;ssl=1 484w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/Capture2.jpg?resize=300%2C287&amp;ssl=1 300w\" sizes=\"auto, (max-width: 484px) 100vw, 484px\" \/><\/a><figcaption class=\"wp-element-caption\">The display for the lab status system<\/figcaption><\/figure>\n<\/div>\n\n\n<p>I have an ESP32 with a BMP280 air pressure \/ temperature sensor, CCS811&nbsp;carbon dioxide \/ volatile organic compounds sensor, two passive infrared sensors for monitoring table occupancy, and a mechanical switch reporting the door status. All this data is sent to a MySQL data every minute, and is available for mining. There is also an LCD display to act as a local user interface. Lots of lovely wires everywhere, of course.<\/p>\n\n\n\n<p>I have found that the BMP280 is sometimes reporting 179 degrees C in the lab, which is about twice the heat in a normal Finnish sauna, and that is not very likely to be reality at the lab. This used to happen rather often, and then the EP32 would get stuck. I first found that BMP280 is a dual mode sensor, with SPI and I2C, and to lock it into I2C which I am using required an extra wire. When you add one between the CSB (chip select bus) pin and 3.3V, the device does believe it must not stray between modes, and the errors decreased significantly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to restart the system remotely?<\/h2>\n\n\n\n<p>Even now I have seen some erroneous values, so I decided to see if it is possible to remotely turn the ESP on and off. Telegram then sprang to my mind, as I had seen it used in the annual IT Seminar for Students that we run with two or three other universities. Once more, Rui Santos came to my assistance with his massive ESP32 site, <a rel=\"noreferrer noopener\" href=\"https:\/\/randomnerdtutorials.com\" target=\"_blank\">randomnerdtutorials.com<\/a>. On that site you have examples on how to use Telegram with ESP32. All it takes is an account on Telegram, a bot set up there by the wonderfully named <strong>Botfather<\/strong>, and a library for Telegram functions on your development environment.<\/p>\n\n\n\n<p>The way it works is that you tell your ESP32 what channel it should listen to, and which user is allowed in. Then system then checks what you sent as input and acts accordingly. Getting the device to return environmental data to me was rather easy, but getting it to reboot was not. <\/p>\n\n\n\n<p>You see, I thought that I could just issue an <strong>ESP32.restart()<\/strong> command inside the Telegram message handler, but that leads into a boot loop, due to a mechanism I am not sure I fully understand. But what you can do is to set a variable inside the message handler the check for the value of it in the main loop, and if it is set to reboot, then use the restart command there.<\/p>\n\n\n\n<p>I&#8217;ll use a simplified example file in this case. I&#8217;m writing a separate piece on the 3D + Robo Lab environmental sentinel. It&#8217;ll be out in three years or so.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a Bot<\/h2>\n\n\n\n<p>All you need to do is to go to Telegram and join the service. <\/p>\n\n\n\n<p>First, search for the IDBot and ask it to give you your user ID:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/idbot.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"664\" height=\"132\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/idbot.png?resize=664%2C132&#038;ssl=1\" alt=\"\" class=\"wp-image-2127\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/idbot.png?w=664&amp;ssl=1 664w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/idbot.png?resize=300%2C60&amp;ssl=1 300w\" sizes=\"auto, (max-width: 664px) 100vw, 664px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Then you can use the search and find Botfather, and issue the command \/newbot (I have masked the proprietary parts, and the image is for a second bot I made for another purpose):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/botfather1.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"665\" height=\"631\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/botfather1.png?resize=665%2C631&#038;ssl=1\" alt=\"\" class=\"wp-image-2125\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/botfather1.png?w=665&amp;ssl=1 665w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/botfather1.png?resize=300%2C285&amp;ssl=1 300w\" sizes=\"auto, (max-width: 665px) 100vw, 665px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Here are the relevant bits of code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;WiFi.h&gt;\n#include &lt;WiFiClientSecure.h&gt;\n#include &lt;UniversalTelegramBot.h&gt;   \/\/ Universal Telegram Bot Library written by Brian Lough: https:\/\/github.com\/witnessmenow\/Universal-Arduino-Telegram-Bot\n#include &lt;ArduinoJson.h&gt;\n\n\/\/ Replace with your network credentials\nconst char* ssid = \"SSID\";\nconst char* password = \"PASSWD\";\n\n\/\/ Initialize Telegram BOT\n#define BOTtoken \"BOT:TOKEN\"  \/\/ your Bot Token (Get from Botfather)\n\n\/\/ Use @myidbot to find out the chat ID of an individual or a group\n\/\/ Also note that you need to click \"start\" on a bot before it can\n\/\/ message you\n#define CHAT_ID \"CHAT_ID\"\n\nUniversalTelegramBot bot(BOTtoken, client);  \/\/create the bot object\n\n\/\/ Checks for new messages every 200 milliseconds.\nint botRequestDelay = 2000;\nunsigned long lastTimeBotRan;<\/code><\/pre>\n\n\n\n<p>After this your ESP32 knows it has a channel for communicating. <\/p>\n\n\n\n<p>A quick look at the setup() is also necessary:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void setup() {\n  pinMode (13, OUTPUT);\n  digitalWrite(13, LOW);\n  Serial.begin(115200);\n  \/\/ Connect to Wi-Fi\n  WiFi.mode(WIFI_STA);\n  WiFi.begin(ssid, password);\n#ifdef ESP32\n  client.setCACert(TELEGRAM_CERTIFICATE_ROOT); \/\/ Add root certificate for api.telegram.org\n#endif\n\n  while (WiFi.status() != WL_CONNECTED) {\n    delay(1000);\n    Serial.println(\"Connecting to WiFi..\");\n  }\n  \/\/ Print ESP32 Local IP Address\n  Serial.println(WiFi.localIP());\n}<\/code><\/pre>\n\n\n\n<p>Next, you need a function that handles the incoming messages and acts on them. This simple example from randomnerdtutorial turns the LED on the board  on and off with <strong>\/lon<\/strong> and <strong>\/loff<\/strong>, <strong>\/start<\/strong> tells you all the commands available to you. Pay attention to the <strong>\/reboot <\/strong>command and how it is handled.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void handleNewMessages(int numNewMessages) {\n  Serial.println(\"handleNewMessages\");\n  Serial.println(String(numNewMessages));\n\n  for (int i = 0; i &lt; numNewMessages; i++) {\n    Serial.print(\"i = \");\n    Serial.println(i);\n    \/\/ Chat id of the requester\n    String chat_id = String(bot.messages&#91;i].chat_id);\n    if (chat_id != CHAT_ID) {\n      bot.sendMessage(chat_id, \"Unauthorized user\", \"\");\n      continue;\n    }\n\n    \/\/ Print the received message\n    String text = bot.messages&#91;i].text;\n    if (text == \"\/reboot\") {\n      bot.messages&#91;i].text = \"\/start\";\n    }\n    Serial.println(text);\n\n    String from_name = bot.messages&#91;i].from_name;\n\n    if (text == \"\/start\") {\n      String welcome = \"Welcome, \" + from_name + \".\\n\";\n      welcome += \"Use the following commands to control your outputs.\\n\\n\";\n      welcome += \"\/lon to turn on led \\n\";\n      welcome += \"\/loff to turn off led\\n\";\n      welcome += \"\/reboot to reset the ESP32\\n\";\n      bot.sendMessage(chat_id, welcome, \"\");\n    }\n\n    if (text == \"\/reboot\") {\n      bot.sendMessage(chat_id, \"ESP will now reboot.\", \"\");\n      forceBoot = 1;\n    }\n\n    if (text == \"\/lon\") {\n      digitalWrite(ledPin, HIGH);\n      bot.sendMessage(chat_id, \"LED is ON\", \"\");\n    }\n\n    if (text == \"\/loff\") {\n      digitalWrite(ledPin, HIGH);\n      bot.sendMessage(chat_id, \"LED is OFF\", \"\");\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>After this, in the loop, all you do is listen for messages and handle them in the <strong>handleNewMessages()<\/strong> function. But when the message is \/reboot, you send the <strong>Boolean forceBoot<\/strong> to 1. See what happens in the loop, if that variable is true:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void loop() {\n  if (millis() &gt; lastTimeBotRan + botRequestDelay)  {\n    int numNewMessages = bot.getUpdates(bot.last_message_received + 1);\n    if (forceBoot == 1) {\n      forceBoot = 0;\n      ESP.restart();\n    }\n    while (numNewMessages) {\n      Serial.println(\"got response\");\n      handleNewMessages(numNewMessages);\n      numNewMessages = bot.getUpdates(bot.last_message_received + 1);\n    }\n    lastTimeBotRan = millis();\n  }\n}<\/code><\/pre>\n\n\n\n<p>So, if the number of new messages is increased by one, then see if forceBoot is true. If it is, reset it to false, issue the command <strong>ESP32.reboot()<\/strong> and enjoy the fruits of your labor as the ESP32 resets itself safely and only once.<\/p>\n\n\n\n<p>Here&#8217;s a picture of the Lab Surveillance System&#8217;s evil backbone machine:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"825\" height=\"825\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235.jpg?resize=825%2C825&#038;ssl=1\" alt=\"\" class=\"wp-image-2128\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?resize=1024%2C1024&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?resize=300%2C300&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?resize=150%2C150&amp;ssl=1 150w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?resize=768%2C768&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?resize=1536%2C1536&amp;ssl=1 1536w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?resize=2048%2C2048&amp;ssl=1 2048w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?w=1650&amp;ssl=1 1650w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2023\/04\/20230420_123235-scaled.jpg?w=2475&amp;ssl=1 2475w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><\/a><\/figure>\n<\/div><div class=\"pvc_clear\"><\/div><p id=\"pvc_stats_2120\" class=\"pvc_stats all  \" data-element-id=\"2120\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif?resize=16%2C16&#038;ssl=1\" border=0 \/><\/p><div class=\"pvc_clear\"><\/div>","protected":false},"excerpt":{"rendered":"<p>Whoops, quite a long time with no posts! Apologies for that, but it&#8217;s been a busier-than-usual year at Haaga-Helia UAS &hellip; <a href=\"https:\/\/www.sabulo.com\/sb\/esp32-development-board\/restarting-an-esp32-via-telegram\/\" class=\"more-link\">More <span class=\"screen-reader-text\">Restarting an ESP32 via Telegram<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_2120\" class=\"pvc_stats all  \" data-element-id=\"2120\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/www.sabulo.com\/sb\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[101,64,104],"tags":[],"class_list":["post-2120","post","type-post","status-publish","format-standard","hentry","category-bmp280","category-esp32-development-board","category-telegram"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6vhqE-yc","_links":{"self":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts\/2120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/comments?post=2120"}],"version-history":[{"count":6,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts\/2120\/revisions"}],"predecessor-version":[{"id":2133,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts\/2120\/revisions\/2133"}],"wp:attachment":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/media?parent=2120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/categories?post=2120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/tags?post=2120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}