Интегрируйте своего 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 заключается в том, что ими можно управлять из любой точки мира. Это дает вашим проектам возможность выйти на новый уровень.
Оригинал