آموزش اتصال ربات تلگرام به آردوینو – قسمت دوم

1
784
اتصال ربات تلگرام به آردوینو
اتصال ربات تلگرام به آردوینو

در قسمت‌اولِ آموزش، چگونگی ساخت ربات‌تلگرام را توضیح دادیم و به‌نحوه‌ی کارکرد و چگونگی برقراری ارتباط با آن پرداختیم. در این‌قسمت از آموزش سعی‌می‌کنیم که بااستفاده‌از برد آردوینو، به ربات ساخته‌شده، جان ببخشیم. فرقی نمی‌کند از کدام مدل برد آردوینو استفاده کنیم. مهم این‌است که بستر اینترنت فعال باشد و ما قادرباشیم داده‌ها را از بستر اینترنت منتقل کنیم. راه‌های زیادی برای اتصال‌به اینترنت وجود دارد؛ مثل استفاده‌از بستر GPRS یا ADSL و راه‌های بسیارِ دیگر. ما سعی می‌کنیم ساده‌ترین راه ممکن را انتخاب کنیم تا از پیچیدگی‌های بی‌مورد کم کنیم. فکر می‌کنم ساده‌ترین و کم‌هزینه‌ترین راه ارتباطی، استفاده‌از بستر WIFI و ماژول ESP8266 باشد. این ماژول از یک پردازنده 80 یا 160 مگاهرتزی استفاده می‌کند که ما را قادر به برنامه‌نویسی مستقیم برروی آن می‌کند.

از چه آردوینویی استفاده خواهیم کرد؟

ماژول Wifi
ماژول Wifi

 

همان‌طورکه قبلاً گفتیم فرقی نمی‌کند و شما به‌راحتی و با درک نحوه‌ی ارتباط، با هر برد دلخواهی، قادر به انجام این ‌کار خواهید بود. تنها کافی است که بستر اینترنت را فراهم کنید. برای کاهش پیچیدگیِ کار ما از ماژول وای فای ESP8266 استفاده خواهیم‌کرد. ماژول ESP8266 یک ماژول Wifi ارزان‌قیمت است که امکان اتصال wifi را فراهم می‌کند. از این ماژول به ۲ صورت می‌توان در پروژه استفاده کرد:

در حالت‌اول ماژول را به برد آردوینو وصل می‌کنیم و بااستفاده‌از دستورات AT و پورت سریال با آن ارتباط برقرار می‌کنیم. دراین روش وجود یک برد پردازنده‌ی مستقل الزامی است.

در حالت‌دوم، برنامه را برروی حافظه ESP8266 بارگذاری می‌کنیم و برنامه توسط پردازنده ESP8266 اجرا می‌شود و نیازی به برد دیگری نیست. قطعاً این روش کم‌هزینه‌تر و سریع‌تر است. لازم‌نیست که حتماً از برد‌های آردوینو موجود استفاده‌کنید. می‌توانید ماژول را تهیه‌کرده و با چند رشته سیم به یک مبدل سریال وصل‌نمایید. خوب کار تمام‌است و فقط کافی‌است برنامه را بنویسید.

اتصال ماژول و برد
اتصال ماژول و برد

 

از چه ویرایشگری استفاده می‌کنیم؟

Arduino IDE
Arduino IDE

 

هنگامی‌که اسم آردوینو می‌آید همه به یاد ادیتور ساده و ابتدایی آردوینو می‌افتند. البته این ویرایشگر برای شروع‌کار مناسب است ولی وقتی‌که قصد داریم به‌صورت حرفه‌ای از آردوینو استفاده کنیم، نقایص این ویرایشگر بیشتر از پیش مشخص می‌شود. شاید اصلا کار به‌جایی برسد که کلاً قید کدنویسی برای آردوینو را بزنید ولی همچنان میتوانید از همان ویرایشگر کلاسیک آردوینو برای کامپایل سورس‌کد استفاده‌کنید.

ربات ما قرار است چه‌کار کند؟

در قسمت‌قبلی از آموزش‌ها نحوه‌ی ساخت ربات تلگرام را با استفاده‌از ربات پدرخوانده (botfather) آموزش دادیم و مقدمات ابتدایی در خصوص نحوه‌ی ارتباط با سرورتلگرام را توضیح‌دادیم. همان‌طور که در ابتدا گفته‌‍شد، در این مقاله قصدداریم که به ربات تلگرام جان‌بخشی کنیم؛ به‌صورتی‌که ربات ما قادربه تعامل با کاربران باشد و بتواند پیام‌های ارسال‌شده توسط کاربر را دریافت کند و بعداز پردازش، پاسخ صحیحی به آن‌ها بدهد.

پس درواقع در این مرحله از آموزش، ربات باید قادر به انجام حداقل دو متد مختلف باشد: اول قادر باشد پیام‌های دریافتی را از سرور تلگرام بخواند و دوم بتواند به کاربران پیام ارسال‌کند.

توضیح متد‌های مورد‌استفاده

در نخستین‌گام ربات باید قادر باشد پیام کاربران را از سرورتلگرام دریافت‌کند. برای خواندن پیامِ کاربران، باید از متد getUpdates برای دریافت آخرین پیام‌ها استفاده کنیم.

همان‌طورکه در سایت تلگرام توضیح داده و در عکس‌زیر مشخص است این تابع دارای تعدادی پارامتر ورودی است که خوشبختانه همه آنها اختیاری هستند و درصورت وارد نکردن آنها خطایی دریافت نمی‌کنید و تابع اجرا خواهد شد.

خروجی تابع هم یک شیء از نوع Update است.

خروجی تابع
خروجی تابع

 

تنها ورودی که در این مرحله به آن احتیاج داریم ورودی offset است. برای روشن‌شدن موضوع بگذارید مسئله‌ای مطرح کنیم: سرور تلگرام از کجا متوجه می‌شود که شما پیام کاربرها را پردازش کرده‌اید؟ درخواست آپدیت به‌تنهایی نمی‌تواند ملاک خوبی برای دریافت پیام‌ها باشد چرا که شاید درهنگام دریافت پیام، اینترنت قطع شد و پیام‌ها به‌دست شما نرسید؛ آن‌وقت تعدادی‌از پیام‌ها را از دست خواهید‌داد.

برای حل این مشکل راه‌حل جالبی وجود دارد که درواقع استفاده‌از offset است. هر پیامِ آپدیتی که از سمت سرور برای شما ارسال می‌شود دارای یک مشخصه ID است که در واقع یک عدد است. اگر شما عدد مذکور را در متغیر offset با فراخوانی این تایع ارسال کنید، تلگرام متوجه خواهد شد شما پیام مذکور را دریافت و پردازش کرده‌اید و پیام مورد‌نظر را از لیست ارسال مجدد به شما حذف خواهد کرد.

برای فراخوانی تابع Getupdates و ارسال پارامتر offset می‌توان از URL زیر استفاده کرد:

https://api.telegram.org/bot<Your Bot Key>/getupdates?offset=2326742

 

ما به‌عنوان‌مثال مقدار ۲۳۲۶۷۴۲ را در متغیر offset قرار دادیم. در‌مثال‌فوق به‌جای عبارت <Your Bot Key> باید کلیدی که هنگام ساخت ربات از تلگرام دریافت‌کردید را قراردهید.

آخرین پیامی که دریافت کرده‌بودیم، مقدار update_id معادل ۲۳۲۶۷۴۱ داشت که پیام مربوطه را دریافت‌و پردازش کردیم برای دریافت پیام بعدی مقدار آنرا یکی افزایش دادیم که پیام بعدی را درصورت وجود بخوانیم.

همان‌طور که در عکس زیر می‌بینید، تلگرام پیام مربوطه را برای ما ارسال کرده‌است:

ارسال پیام مربوطه از سمت تلگرام
ارسال پیام مربوطه از سمت تلگرام

 

آپدیت ارسال‌شده حاوی مشخصات فرستنده و متن پیام است.

برای ارسال پیام باید از تابع SendMessage استفاده کنیم.

تابع SendMessage
تابع SendMessage

 

این تابع نیاز دارای چندین پارامتر ورودی است، ولی به‌جز دو پارامتر chat_id و text، مابقی پارامتر‌ها اختیاری هستند و می‌توان از آن‌ها چشم‌پوشی کرد.

پارامتر chat_id در واقع یک عدد منحصر‌به‌فرد برای هر فردی است که دارد با ربات چت می‌کند. تلگرام از این طریق متوجه می‌شود که پیام مورد‌نظر به چه شخصی ارسال شود. در عکس زیر مقدار آن مشخص شده است:

مقدار chat_id
مقدار chat_id

پارامتر دوم text در واقع متنی است که باید ارسال شود.

فرض کنید می‌خواهیم پیام salam را برای کاربر ارسال کنیم. باتوجه‌به عکس فوق، id کاربر عدد 334577197 است. تابع SendMessage به‌شکل‌زیر باید فراخوانی شود:

https://api.telegram.org/bot<Your Bot Key>/sendMessage?chat_id=334577197&text=salam%20sisoog

 

دقت داشته‌باشید در صورتی پیام به کاربر ارسال می‌شود که کاربر قبلاً ربات را Start کرده باشد؛ یعنی یک بار دستور /Start را برای ربات ارسال کرده باشد.

ارسال موفقیت‌آمیز پیام
ارسال موفقیت‌آمیز پیام

در‌صورتی‌که پیام با موفقیت ارسال شده‌باشد، مطابق عکس فوق نتیجه را گزارش خواهد کرد.

برنامه‌ی آردوینو

قبل‌از هر چیزی لازم‌است که تغییراتی در برنامه لحاظ کنید تا برنامه قادر باشد به WIFI و تلگرام متصل شود. پس مقادیر زیر را در برنامه اصلاح کنید:

#define Ssid "Your_WIFI_SSID"
#define Password "Your_WIFI_PASS"
#define Bot_Key "Your_BOT_Key"

 

SSID یا اسم شبکه‌ی WIFI را باید در گزینه‌ی اول وارد کنید. گزینه‌ی دوم رمز عبور وای‌فای است و گزینه‌ی‌سوم هم کلید ربات تلگرام است که باید درون کتیشن‌ها (علامت نقل‌قول) بدون فاصله وارد کنید.

#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include "ZeusTgBot.h"




ESP8266WiFiMulti WiFiMulti;
#define Ssid "Your_WIFI_SSID"
#define Password "Your_WIFI_PASS"
#define Bot_Key "Your_BOT_Key"

Zeus_TgBot Bot(Bot_Key);

// Witty Cloud Board specifc pins
const int LDR = A0;
const int BUTTON = 4;
const int RED = 15;
const int GREEN = 12;
const int BLUE = 13;


void Tg_Message_Prossess(uint32_t mgs_id,uint32_t sender_id,String msg);

void setup()
{
// Add your initialization code here
Serial.begin(115200);
Serial.print("\n");
//Serial.setDebugOutput(true);

// We start by connecting to a WiFi network
WiFiMulti.addAP(Ssid, Password);

Serial.println();
Serial.println();
Serial.print("Wait for WiFi... ");

/*Wait For Connect to Server*/
while(WiFiMulti.run() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.println();
Serial.println("Connect to NetWork .... OK");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

// Initialize LDR, Button and RGB LED
pinMode(LDR, INPUT);
pinMode(BUTTON, INPUT);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);

Bot.Set_Message_Event(&Tg_Message_Prossess);
Zeus_TgBot::User_t User;
if(Bot.GetMe(&User))
{
Serial.println();
Serial.println("Bot Information");
Serial.println("first name: " + User.first_name);
Serial.println("last_name: " + User.last_name);
Serial.println("username: " + User.username);
Serial.println();
}
else
{
Serial.println("Can Not Get Bot Info");
}
}

void Tg_Message_Prossess(uint32_t mgs_id,uint32_t sender_id,String msg)
{

Serial.println("Get Message - "+msg);
Serial.println(mgs_id);
Bot.sendMessage(sender_id, msg);
}


// The loop function is called in an endless loop
void loop()
{
//Add your repeated code here
digitalWrite(GREEN, true);
Bot.GetUpdates();
digitalWrite(GREEN, false);
delay(1000);

}

 

در‌صورتی‌که مشکلی وجود نداشته باشد، لاگی مطابق لاگ زیر دریافت خواهید‌کرد. در لاگ زیر وضعیت کانکت‌شدن به شبکه WIFI و مشخصات ربات را در شروع برنامه نمایش می‌دهد:

Connect to NetWork .... OK
WiFi connected
IP address: 
192.168.1.120

Bot Information
first name: Sisoog_arduino
last_name: 
username: Sisoog_arduinobot

 

برنامه چطور کار می‌کند؟

تا جای ممکن سعی‌کردیم که برنامه را در ساده‌ترین حالت ممکن پیاده‌سازی کنیم. برای همین یک کلاس (کتابخانه) به اسم Zeus_TgBot ایجاد کردیم که تمام اتفاقات مربوط به ربات و ارتباط با سرور تلگرام درون آن انجام می‌شود و از چشم کاربر دور بماند. البته شما می‌توانید سورس این کتابخانه را مرور کنید و اطلاعاتی را راجع‌ به آن به‌دست بیاورید.

کلاس مذکور به‌شکل زیر تعریف شده‌است:

typedef void (*Message_Event) (uint32_t mgs_id,uint32_t sender_id,String msg);

class Zeus_TgBot {
public:

typedef struct
{
uint32_t id;
String first_name;
String last_name;
String username;
}User_t;

Zeus_TgBot(String token);
virtual ~Zeus_TgBot();

void Set_Message_Event(Message_Event Event_Call);
bool GetMe(User_t *User);
bool GetUpdates();
bool sendMessage(uint32_t chat_id, String text);

private:
String botkey;
StaticJsonBuffer<4096> jsonBuffer;
WiFiClientSecure client;
volatile uint32_t UpdateID;

String SendCommand(String command);
void ProssessOneMessage(String msg);
Message_Event Func_Message_Event;
};

 

درواقع این کلاس درحال‌حاضر 4 متد برای کار با تلگرام دارد.

در ابتدا باید یک شیء از این کلاس ایجاد کنید. برای ایجاد یک شیء نیاز است که شما کلید ارتباطی با ربات را وارد کنید.

مطابق خط 13 برنامه اصلی:

Zeus_TgBot Bot(Bot_Key);

 

تابع بعدی تابع Set_Message_Event است که درواقع این تابع آدرس یک متد را دریافت می‌کند و هر وقت پیام جدیدی از کاربر دریافت‌شد آن متد را فراخوانی می‌کند. متد باید به شکل‌خاصی تعریف‌شود تا کلاس بتواند آنرا فراخوانی کند.

این تایع در خط 58 از برنامه‌ی اصلی مورد‌استفاده قرار گرفته‌است:

Bot.Set_Message_Event(&Tg_Message_Prossess);

 

تابع بعدی GetUpdates است که درواقع باید در بازه‌های خاص زمانی فراخوانی شود. با هربار فراخوانی این تابع، بررسی می‌شود که آیا پیام جدیدی برای پردازش وجود دارد یا نه؟

این تابع در خط 89 از برنامه‌ی اصلی مورد‌استفاده قرار گرفته‌است:

Bot.GetUpdates();

 

و آخرین تابع هم sendMessage است که در ورودی، ID کاربری را دریافت می‌کند و در ادامه متن پیامی که قرار است ارسال‌شود و پیام را برای کاربر مورد‌نظر ارسال می‌کند.

void Tg_Message_Prossess(uint32_t mgs_id,uint32_t sender_id,String msg)
{

Serial.println("Get Message - "+msg);
Serial.println(mgs_id);
Bot.sendMessage(sender_id, msg);
}

 

تمام اتفاقات درون تابع Tg_Message_Prossess می‌افتد که در برنامه‌ی اصلی پیاده‌سازی کردیم. این تایع را به کلاس Zeus_TgBot معرفی کردیم تا با دریافت هرباره پیام، فراخوانی‌شود. با فراخوانی این تابع سه پارامتر به آن انتقال داده می‌شود. پارامتر اول شماره‌ی پیام است. هر پیام دارای یک مشخصه منحصر‌به‌فرد است که بعد‌ها با آن کار خواهیم کرد. پارامتر بعدی مشخصه‌ی فردی است که پیام را ارسال کرده‌است. در آخر متن پیام وجوددارد.

پیامی که دریافت کرده‌ایم را مجدداً به فرستنده ارسال می‌کنیم و این اولین قدم است برای جان بخشیدن به ربات.

تا این مرحله، علاوه بر برقراری ارتباط با سرور تلگرام، قادر بودیم که پیام‌های ارسال‌شده را دریافت‌کنیم و آن‌ها را مجدداً به فرستنده ارسال‌کنیم. می‌توانیم برای کامل‌تر شدن، پیام‌ها را تغییردهیم و بعد ارسال‌کنیم. این کاری‌است که قرار است در مقاله‌ی بعدی این آموزش به آن بپردازیم.

در مقاله‌ی بعدی نحوه اتصال دستگاه به ربات تلگرام، بدون نیاز به فیلترشکن را آموزش خواهیم‌داد.

دانلود سورس آردوینو:

ESP_Telegram

ESP8266_TelegramBot-0.1.tar

ESP8266_TelegramBot-0.1

 

 

منبع: سیسوگ

مطلب قبلیآموزش اتصال ربات تلگرام به آردوینو – قسمت اول
مطلب بعدینکات و ترفندهای بهینه سازی برنامه C برای میکروکنترلر AVR -قسمت دوم

1 نظر

پاسخ دهید

لطفا نظر خود را وارد کنید!
لطفا نام خود را در اینجا وارد کنید