Интегрируйте своего Telegram-бота с реальным миром через микроконтроллер ESP32/ESP8266 Arduino

Интегрируйте своего Telegram-бота с реальным миром через микроконтроллер ESP32/ESP8266 Arduino

21 марта 2022 г.

В этой статье я расскажу вам, как написать телеграм-бота, который интегрируется с реальным миром через


микроконтроллер (ардуино).


На практике все запоминается лучше. Итак, я объясню все через практический проект из моего опыта. Код проекта опубликован на моем GitHub страница проекта Smart Queue. В этой статье объясняется, как создать телеграмм-бота, обрабатывать сообщения и отвечать пользователям. Также, в конце, будут даны некоторые идеи для будущих проектов для вас.


Коротко о проекте


Я сделал проект для управления очередью в нашу офисную игровую комнату с помощью Telegram на базе Arduino. Arduino с серводвигателем был установлен для блокировки и разблокировки двери. Люди могли встать в очередь и проверить, сколько человек в очереди, с помощью телеграмм-бота.


В этом проекте использовался NodeMCU, но та же логика работает и для Arduino с ESP32/ESP8266.


Телеграмма


Telegram — это мессенджер с мобильными приложениями (iPhone и Android) и настольными приложениями (Mac, Windows и Linux). В Telegram у нас есть возможность создать бота. Мы будем управлять им с помощью нашего микроконтроллера, обрабатывая сообщения от пользователей.


Создание Telegram-бота


Чтобы создать Telegram-бота, нам нужно запросить его у телеграмм-бота «botfather». Все, что вам нужно, это найти бота по поиску или получить его по ссылке: https://t.me/botfather. Бот удобен для пользователя, и когда вы откроете чат с ботом, наши дальнейшие действия должны быть ясны для вас.


Отправьте команду /start для запуска бота. Отправьте команду /newbot для создания нового бота. Нас попросят ввести имя и имя пользователя нового бота. После успешного создания бота бототец отправит нам токен. Этот потребуется для получения всех сообщений, отправленных боту, и отправки сообщений от бота пользователям.


Связь


Мы будем использовать серводвигатель для блокировки и разблокировки двери и светодиод, чтобы указать, заперта ли дверь.


Серводвигатели имеют 3 контакта: оранжевый, красный и коричневый: красный — 5В, коричневый — GND, оранжевый — 14. Светодиод подключен к контакту 2.


код


Прежде всего, мы должны импортировать все необходимые библиотеки:


```нажмите


ifdef ESP32


include


еще


include


endif


include


include


include


include


сервопривод;


Напишите учетные данные wi-fi, к которому будет подключен микроконтроллер:


```нажмите


const char* ssid = ""; // имя Wi-Fi


const char* пароль = ""; // пароль Wi-Fi


Напишите токен нашего бота, который мы получили после его создания:


```нажмите


// Инициализировать Telegram BOT


define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // ваш токен бота (получить от Botfather)


Определите выходы и другие необходимые переменные:


```нажмите


// Проверяет наличие новых сообщений каждые 0,1 секунды.


интервал botRequestDelay = 100;


unsigned long lastTimeBotRan;


int servo_pin = 14;//сервопин


интервал servo_locked_value = 180;


интервал servo_unlocked_value = 30;


const int ledPin = 2;


Строка queue[10] ={};//массив очереди


int queue_array_len = 0;//длина очереди


bool room_is_free = true;//изначально комната свободна


bool door_is_locked = true;// дверь заперта


Создайте новый wi-fi клиент и бота с токеном и клиентом:


```нажмите


клиент WiFiClientSecure;


бот UniversalTelegramBot(BOTтокен, клиент);


В разделе настройки мы инициализируем светодиод и сервопривод, запустим последовательный порт и подключимся к wi-fi:


```нажмите


недействительная установка () {


Серийный.начать(115200);


ifdef ESP8266


configTime(0, 0, "pool.ntp.org"); // получить время UTC через NTP


client.setTrustAnchors(&cert); // Добавляем корневой сертификат для api.telegram.org


endif


pinMode(ledPin, ВЫХОД);


цифровая запись (светодиод, ВЫСОКИЙ);


// Подключиться к Wi-Fi


WiFi.режим(WIFI_STA);


WiFi.begin(ssid, пароль);


ifdef ESP32


client.setCACert (TELEGRAM_CERTIFICATE_ROOT); // Добавляем корневой сертификат для api.telegram.org


endif


в то время как (WiFi.status ()! = WL_CONNECTED) {


задержка(1000);


Serial.println("Подключение к WiFi..");


// Печать локального IP-адреса ESP32


Serial.println(WiFi.localIP());


//Сервопривод - закрыть:


myservo.attach(servo_pin);


myservo.write(180);


В разделе цикла мы сделаем три основные вещи:


  • проверить, нет ли новых сообщений телеграм-боту;

  • проверить, свободна ли комната, и если да, то пригласить следующего человека в очереди;

  • указать, заперта ли дверь и открыть/закрыть дверь

```нажмите


недействительный цикл () {


если (millis() > lastTimeBotRan + botRequestDelay) {


int numNewMessages = bot.getUpdates(bot.last_message_received + 1);


в то время как (numNewMessages) {


Serial.println("получил ответ");


обработать новые сообщения (число новых сообщений);


numNewMessages = bot.getUpdates(bot.last_message_received + 1);


lastTimeBotRan = миллис();


//проверяем, свободна ли комната


if(room_is_free ==true && очередь[0]!=""){


room_is_free = ложь;


//приглашаем в комнату:


Serial.println("Приглашение в комнату: "+queue[0]);


bot.sendMessage(queue[0], "Комната свободна!
Пожалуйста, подойдите и отправьте /unlock_the_door_from_outside, чтобы открыть дверь.", "");


//Указание и открытие/закрытие двери:


digitalWrite(ledPin, door_is_locked);//ledState


если(дверь_заперта){


myservo.write(servo_locked_value);//заблокировано


}еще{


myservo.write(servo_unlocked_value);//разблокировано


Вот как мы будем обрабатывать новые сообщения и отвечать на сообщение /start:


```нажмите


void handleNewMessages (int numNewMessages) {


Serial.println("handleNewMessages");


Serial.println(String(numNewMessages));


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


// Идентификатор чата запрашивающего


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


// Печатаем полученное сообщение


Текст строки = bot.messages[i].text;


Serial.print("От: ");Serial.println(chat_id);


Serial.print("Сообщение: ");Serial.println(текст);


Строка from_name = bot.messages[i].from_name;


если (текст == "/старт") {


String welcome = "Добро пожаловать, " + from_name + ".
";


welcome += "С этим ботом можно отстоять очередь в Игровую комнату.
";


welcome += "Пожалуйста, посмотрите мои /options.

";


bot.sendMessage(chat_id, приветствие, "");


Вот как мы отвечаем на сообщение /options и отправляем кнопки для удобства взаимодействия:


```нажмите


если (текст == "/параметры") {


String keyboardJson = "[[\"/Stand_in_line\"],[\"/cancel\", \"/status\"]]";


bot.sendMessageWithReplyKeyboard(chat_id, "Вот мои варианты:", "", keyboardJson, true);



Когда мы получаем сообщение /Stand_in_line, нам нужно проверить, уже ли человек находится в очереди, а если нет, то добавить человека в очередь и сообщить об этом:


```нажмите


если (текст == "/Stand_in_line") {


//проверяем, уже ли человек в очереди:


если (if_chat_id_not_in_queue (chat_id)) {


// добавляем человека в очередь


queue[queue_array_len] = chat_id;//массив очереди


очередь_массива_len++;


bot.sendMessage(chat_id, "Вы присоединились к очереди.", "");


}еще{


bot.sendMessage(chat_id, "Вы уже в очереди.", "");


//печатаем очередь


очередь печати();



**
**


Когда мы получаем сообщение /cancel, нам нужно удалить человека из очереди, проверив, есть ли он там. Также, если человек уже был приглашен в комнату, мы вернем статус комнаты на свободную.


```нажмите


если (текст == "/отмена") {


//проверяем, уже ли человек в очереди:


если (if_chat_id_not_in_queue (chat_id)) {


bot.sendMessage(chat_id, "Вас не было в очереди.", "");


}еще{


// проверяем, освободил ли место тот, кто первым освободил место.


если (queue[0]=chat_id){


room_is_free = истина;


//удаляем человека из очереди


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


если (очередь [я] = идентификатор чата) {


очередь[я] = "";


//перемещаем элементы после удаленного:


for(int j = i;j <queue_array_len; j++){


очередь[j] = очередь[j+1];


очередь_массив_длина--;


bot.sendMessage(chat_id, "Вы больше не в очереди.", "");


//печатаем очередь


очередь печати();



Когда мы получим сообщение /status, мы отправим, сколько человек в очереди, и если человек в ней, мы также отправим позицию человека в очереди:


```нажмите


если (текст == "/статус") {


//печатаем очередь


очередь печати();


int current_person_id_in_queue = -1;


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


если(очередь[i]==chat_id){


current_person_id_in_queue = i+1;


String message = "Очередь состоит из " + String(queue_array_len ) + " человек(а).
";


если (current_person_id_in_queue! = -1) {


message +="Вы #"+String(current_person_id_in_queue)+ " в очереди.
";


bot.sendMessage(chat_id, сообщение, "");



Когда придет очередь людей, мы отправим сообщение с приглашением:



Когда мы получаем сообщение /unlock_the_door_from_outside, нам нужно проверить, является ли человек первым в очереди, и если да, то разблокировать дверь и отправить ответ:


```нажмите


если (текст == "/unlock_the_door_from_outside") {


//проверка первого человека в очереди:


если(chat_id == очередь[0]){


door_is_locked = ложь;


myservo.write(servo_unlocked_value);//разблокировано


bot.sendMessage(chat_id, "Дверь открыта!
Войдите и заприте дверь, отправив команду /lock_the_door_from_inside.", "");


}еще{


bot.sendMessage(chat_id, "Что-то пошло не так.
Пожалуйста, попробуйте проверить свой статус в очереди с помощью команды /status.", "");


В следующих командах /lock_the_door_from_inside и /unlock_the_door_from_inside как прежде чем нам нужно проверить, является ли человек первым в очереди. Мы делаем это, чтобы убедиться, что дверь заперта или разблокирована нужным человеком.


Для сообщения /lock_the_door_from_inside нам нужно просто запереть дверь:


```нажмите


если (текст == "/lock_the_door_from_inside") {


//проверка первого человека в очереди:


если(chat_id == очередь[0]){


door_is_locked = истина;


myservo.write(servo_locked_value);//заблокировано


bot.sendMessage(chat_id, "Дверь заперта!
Чтобы открыть дверь, отправьте команду /unlock_the_door_from_inside.", "");


}еще{


bot.sendMessage(chat_id, "Что-то пошло не так.
Пожалуйста, попробуйте проверить свой статус в очереди с помощью команды /status.", "");


Когда мы получим сообщение /unlock_the_door_from_inside, мы откроем дверь на три секунды и закроем ее обратно. Кроме того, мы удалим человека из очереди и вернем статус комнаты на свободный. Для этого требуется пригласить следующего человека из очереди:


```нажмите


если (текст == "/unlock_the_door_from_inside") {


//проверка первого человека в очереди:


если(chat_id == очередь[0]){


door_is_locked = ложь;


myservo.write(servo_unlocked_value);//разблокировано


bot.sendMessage(chat_id, "Дверь открыта! Мы закроем ее через 3 секунды", "");


задержка(3000);


door_is_locked = истина;


room_is_free = истина;


myservo.write(servo_locked_value);//заблокировано


//удаляем человека из очереди


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


если (очередь [я] = идентификатор чата) {


очередь[я] = "";


//перемещаем элементы после удаленного:


for(int j = i;j <queue_array_len; j++){


очередь[j] = очередь[j+1];


очередь_массив_длина--;


bot.sendMessage(chat_id, "Дверь заперта. Пока!", "");


}еще{


bot.sendMessage(chat_id, "Что-то пошло не так.
Пожалуйста, попробуйте проверить свой статус в очереди с помощью команды /status.", "");



Вот наши вспомогательные функции. Эти две части кода используются много раз. Итак, я решил разделить их для удобства кода:


```нажмите


//проверяем, уже ли человек в очереди:


bool if_chat_id_not_in_queue(String chat_id){


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


если(chat_id == очередь[i]){


вернуть ложь;


вернуть истину;


//печатаем очередь


недействительным print_queue () {


Serial.print("В очереди - "); Serial.println(queue_array_len);


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


Serial.println (очередь [i]);


Заключение


Из этого руководства вы узнали, как взаимодействовать с вашим микроконтроллером с помощью Telegram Bot.


Микроконтроллер может обрабатывать сообщения, отправленные боту, и отправлять сообщения обратно.


Этот проект является примером и демонстрацией для вас. Возможности ограничены вашим воображением. Вот несколько идей для вас: сделайте детектор движения, который будет посылать сообщение при обнаружении движения; подключить модуль камеры и отправить изображение по запросу; управлять светодиодной лентой или получить индикацию любого датчика. Кроме того, можно было бы сделать глобальный проект, например, сделать большую светодиодную матрицу и дать контроль над ней всем с помощью телеграмм-бота.


Самое замечательное в проектах интегрированных ботов Telegram заключается в том, что ими можно управлять из любой точки мира. Это дает вашим проектам возможность выйти на новый уровень.



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE