در این آموزش قصد داریم، برای کنترل آردوینو از راه دور یک شبکه WiFi اختصاصی را توسط ماژول ESP8266 ایجاد کنیم و سپس با اپلیکشن نصبشده روی موبایل خود، دستورات لازم را از طریق این شبکه به آردوینو انتقال دهیم. در واقع ما یک آردوینو را با استفاده از ماژول ESP به یک شبکه وای فای متصل میکنیم و با این کار بین آردوینو و سایر دستگاههای الکترونیکی در محیط، ارتباط بی سیم برقرار میکنیم، که درنهایت به شکلگیری بسیاری از پروژههای کاربردی مربوط به اینترنت اشیاء کمک خواهد کرد. اگرشما هم به انجام پروژههای مربوط به اینترنت اشیاء IOT مثل کنترل وسایل برقی با موبایل در یک خانه هوشمند علاقهمند هستید، تا پایان این آموزش با ما همراه باشید.
در طراحی و پیادهسازی پروژههای اینترنت اشیاء، روشهای زیادی برای استفاده از یک ماژول ESP8266 وجود دارد، که در برخی روشها ممکن است از این ماژول برای ارسال و دریافت دادهها بهصورت آنلاین یا برای آپلود منظم دادهها استفاده کنند. این ماژل وای فای با توانایی ایجاد یک شبکه بیسیم در این آموزش به ما کمک میکند تا با استفاده از گوشی موبایل (آیفون یا اندروید)، بتوانیم از راه دور با آردوینو ارتباط برقرار کنیم. این امر بهصورت آفلاین انجام میشود و نیازی به اتصال به اینترنت نخواهیم داشت، زیرا همانطور که دانستیم ماژول ESP8266-01 در این پروژه بهعنوان یک نقطه دسترسی عمل میکند و با ایجاد یک شبکه WiFi مستقل، اجازه میدهد سایر دستگاههای الکترونیکی به این شبکه متصل و توسط آردوینو کنترل شوند.
بدانیم:
بهطور کلی ماژول ESP8266 در دو مد ایستگاه و نقطه دسترسی قابل استفاده میباشد:
- مد ایستگاه (station mode) :
وقتی یک ماژول ESP8266 به یک شبکه وای فای موجود (که توسط روتر وایرلس شما از قبل ایجاد شده) متصل شود، اصطلاحاً میگوییم ماژول در مد ایستگاه قرار دارد.
- مد نقطه دسترسی (Access Point) :
در مد نقطه دسترسی، ماژول ESP8266 شبکه وای فای خود را ساخته (یک شبکه وای فای مستقل) و مانند روتر وای فای عمل میکند.
سختافزار و نرمافزار موردنیاز
پس از آشنایی با هدف کلی این پروژه، نوبت به فراهم کردن تجهیزات سختافزاری و نرمافزاری مربوط به ایجاد ارتباط و کنترل از راه دور آردوینو با موبایل میرسد.
- ماژول Arduino UNO
- ماژول ESP-01 با هسته وای فایESP8266
- تعدادی سیم جامپر
- یک عدد مقاومت 1 کیلو اهم
- دو عدد مقاومت 10 کیلو اهم
آشناییبا سختافزارها
پیش از شروع به ساخت مدار کنترل از راه دور با موبایل و تنظیمات لازم در این پروژه، ما نیاز داریم تا با ساختار و نحوه عملکرد تجهیزات اصلی مورد کاربرد در آن، آشنا شویم:
معرفی ماژول آردوینو UNO
آردوینو UNO یک برد میکروکنترلر اپنسورس مبتنیبر میکروکنترلر ATmega328P است. این برد شامل تعدادی ورودی-خروجی آنالوگ و دیجیتال (GPIOs) است که میتوانند به سنسورهای مختلف، محرکها، بردهای توسعه و مدارهای دیگر متصل شوند. ازجمله ویژگیهای آردوینو UNO میتوان به موارد زیر اشاره کرد:
- 14 پین ورودی-خروجی دیجیتال (که 6 پین آن میتواند به عنوان خروجی PWM استفاده شود)
- 6 ورودی آنالوگ
- رزوناتور سرامیکی 16 مگاهرتز
- 32 کیلوبایت حافظه فلش (0.5 کیلوبایت مورد استفاده بوت لودر)
- 2 کیلوبایت حافظه SRAM
- 1 کیلوبایت حافظه EEPROM
- دارای جک آداپتور مادگی و کانکتور USB
معرفی ماژول ESP-01
ESP-01 یک ماژول وای فای کوچک با تراشهی ESP8266 است که این تراشه از پروتکل TCP/IP پشتیبانی میکند. بنابراین با استفاده از آن میتوانید به شبکه های دیگر مانند LAN یا اینترنت متصل شده یا یک شبکه مجزا را ایجاد کنید و پروژههای خود را به ارتباط WiFi مجهز کنید. این ماژول دارای آنتن داخلی است و با ولتاژ 3.3 ولت کار میکند. همچنین دارای پینهایی برای برقراری ارتباط سریال میکروکنترلرهای دیگر است. همچنین برای ارتباط با این ماژول میتوان از دستورات AT بهره گرفت یا حافظه فلش آن را پروگرام کرد تا مانند یک میکروکنترلر، عملیات دلخواه ما را انجام دهد اما توجه شود که این ماژول آی سی مبدل سریال ندارد و برای پروگرام کردن آن به یک مبدل USB به سریال 3.3 ولت نیاز است.
شماتیک مدار
در آغاز کار، ما برای کنترل آردوینو در شبکه نیاز داریم که مطابق جدول و شماتیک زیر ماژول ESP8266-01 را به یک آردوینو UNO متصل کنیم :
بدینمنظور مراحل زیررا بهترتیب دنبال و با توجه به شماتیک آماده شده اتصالات را کامل میکنیم:
- پینVCC و پین Enable ماژول ESP8266 را با استفاده از یک مقاومت 10 کیلواهم به پین تغذیه 3.3 ولت آردوینوUno متصل کنید. (سیمهای قرمز)
- پین GND ماژول ESP8266 را به پین GNG آردوینوUNO متصل نمایید. (سیم مشکی)
- پین Tx ماژول ESP8266 را به پین شماره 3 آردوینوUNO متصل کنید. (سیم سبز)
- پین Rx ماژول ESP8266 را با استفاده از یک مقاومت 1 کیلواهم به پین شماره 2 آردوینو و با استفاده از یک مقاومت 1 کیلواهم دیگر پین RX را به پین GNDآردوینو متصلکنید. (سیم آبی)
نحوه سیمکشی و اتصالات در شکل زیر نمایش داده شده است :
توجه داشته باشید :
- پین تغذیه در نسخه 11 ماژول ESP که در این آموزش استفاده کردیم، به صورت VIN نام گذاری شدهاست. اما در نسخههای دیگر این ماژول، میتواند به صورت POWER یا VCC نیز نامگذاری شده باشد.
- برای ماژول راهاندازی شود میبایست پین CH_EN یا Enable هم حتماً به VCC متصل شود.
- برای تغذیه ماژول ESP هرگز بیشتر از 3.3 ولت استفاده نکنید. زیرا استفاده از ولتاژی بیش از این مقدار، منجر به آسیب دیدن ماژول خواهدشد. از آنجایی که ما از ولتاژ تغذیه 5 ولت برای آردوینو استفاده کردیم، با یک تقسیم مقاومتی با کمک مقاومتهای 1 کیلواهم بهعنوان تقسیم کنندهی ولتاژ، ولتاژ 3.3 ولت را برای ماژول ESP تأمین کردیم.
- پایههای TX و RX در آردوینوUNO را به ترتیب به پایههای RX و TX در ماژول ESP متصل نمودیم تا ارسال و دریافت اطلاعات بین ماژول ESP و آردوینوUNO از طریق ارتباط سریال صورت گیرد.
- قبل از پروگرام کردن آردوینو، باید پایه های RX و TX را از ماژول ESP جدا کنید و بعد از پروگرام شدن آردوینو، مجددا اتصالات را برقرار کنید.
- پس از برقراری اتصالات به صورتی که توضیح داده شد قادر به برقراری ارتباط با ماژول خواهیم بود.
کد آردوینو :
در این بخش یک تکهکد قرار داده شده که لازم است آن را برروی محیط IDE آردوینو خود آپلود و پروگرم نمایید.
#include <SoftwareSerial.h>
SoftwareSerial wifiSerial(2, 3); // RX, TX for ESP8266
bool DEBUG = true; //show more logs
int responseTime = 10; //communication timeout
void setup()
{
pinMode(13,OUTPUT); //set build in led as output
// Open serial communications and wait for port to open esp8266:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
wifiSerial.begin(115200);
while (!wifiSerial) {
; // wait for serial port to connect. Needed for Leonardo only
}
sendToWifi("AT+CWMODE=2",responseTime,DEBUG); // configure as access point
sendToWifi("AT+CIFSR",responseTime,DEBUG); // get ip address
sendToWifi("AT+CIPMUX=1",responseTime,DEBUG); // configure for multiple connections
sendToWifi("AT+CIPSERVER=1,80",responseTime,DEBUG); // turn on server on port 80
sendToUno("Wifi connection is running!",responseTime,DEBUG);
}
void loop()
{
if(Serial.available()>0){
String message = readSerialMessage();
if(find(message,"debugEsp8266:")){
String result = sendToWifi(message.substring(13,message.length()),responseTime,DEBUG);
if(find(result,"OK"))
sendData("\nOK");
else
sendData("\nEr");
}
}
if(wifiSerial.available()>0){
String message = readWifiSerialMessage();
if(find(message,"esp8266:")){
String result = sendToWifi(message.substring(8,message.length()),responseTime,DEBUG);
if(find(result,"OK"))
sendData("\n"+result);
else
sendData("\nErrRead"); //At command ERROR CODE for Failed Executing statement
}else
if(find(message,"HELLO")){ //receives HELLO from wifi
sendData("\\nHI!"); //arduino says HI
}else if(find(message,"LEDON")){
//turn on built in LED:
digitalWrite(13,HIGH);
}else if(find(message,"LEDOFF")){
//turn off built in LED:
digitalWrite(13,LOW);
}
else{
sendData("\nErrRead"); //Command ERROR CODE for UNABLE TO READ
}
}
delay(responseTime);
}
/*
* Name: sendData
* Description: Function used to send string to tcp client using cipsend
* Params:
* Returns: void
*/
void sendData(String str){
String len="";
len+=str.length();
sendToWifi("AT+CIPSEND=0,"+len,responseTime,DEBUG);
delay(100);
sendToWifi(str,responseTime,DEBUG);
delay(100);
sendToWifi("AT+CIPCLOSE=5",responseTime,DEBUG);
}
/*
* Name: find
* Description: Function used to match two string
* Params:
* Returns: true if match else false
*/
boolean find(String string, String value){
return string.indexOf(value)>=0;
}
/*
* Name: readSerialMessage
* Description: Function used to read data from Arduino Serial.
* Params:
* Returns: The response from the Arduino (if there is a reponse)
*/
String readSerialMessage(){
char value[100];
int index_count =0;
while(Serial.available()>0){
value[index_count]=Serial.read();
index_count++;
value[index_count] = '\0'; // Null terminate the string
}
String str(value);
str.trim();
return str;
}
/*
* Name: readWifiSerialMessage
* Description: Function used to read data from ESP8266 Serial.
* Params:
* Returns: The response from the esp8266 (if there is a reponse)
*/
String readWifiSerialMessage(){
char value[100];
int index_count =0;
while(wifiSerial.available()>0){
value[index_count]=wifiSerial.read();
index_count++;
value[index_count] = '\0'; // Null terminate the string
}
String str(value);
str.trim();
return str;
}
/*
* Name: sendToWifi
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendToWifi(String command, const int timeout, boolean debug){
String response = "";
wifiSerial.println(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(wifiSerial.available())
{
// The esp has data so display its output to the serial window
char c = wifiSerial.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.println(response);
}
return response;
}
/*
* Name: sendToUno
* Description: Function used to send data to Arduino.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendToUno(String command, const int timeout, boolean debug){
String response = "";
Serial.println(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(Serial.available())
{
// The esp has data so display its output to the serial window
char c = Serial.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.println(response);
}
return response;
}
تنظیمات ماژول ESP-01 برروی موبایل
هنگامیکه همهی اتصالات فیزیکی در شبکه، انجام و برنامه در آردوینو پروگرم شد، ماژول وای فای ESP8266 شما در لیست WiFi موبایل شما قابل مشاهده خواهدبود، بنابراین میتوانید تنظیمات موردنظر خود را در شبکه اعمال نمایید:
- ابتدا اپلیکیشن TCP Client را بسته به نوع سیستمعامل موبایل خود دانلود و سپس آن را نصب کنید.
ما در این پروژه از برنامه TCP Client مخصوص سیستم عامل اندروید استفاده کردیم.
2. در لیست وای فای تلفنهمراه خود، ماژولESP8266 را جستجو و به آن متصل شوید.
چنانچه نمیتوانید ماژول ESP8266 را در لیست شبکه های وای فای دردسترس مشاهده کنید، مطمئن شوید اتصالات به درستی انجام شده است و آردوینو شما روشن و درحال اجرا است. (معمولاً نام وای فای ESP با نام ورژن آن مانند ESP11 همراه است.)
3. پس از اتصال تلفن همراه به ماژول، آدرس IP استاتیک را پیدا کنید.
توجه :
برای مشاهده آدرس IP ماژول ESP خود میتوانید به قسمت تنظیمات وای فای یک موبایل مراجعه کنید و سپس در بخش دادههای مربوط به شبکه، این آدرس را ببینید.
به صورت پیشفرض آدرس IP در مد AP برابر است با 192.168.4.1 بنابراین شما برای تغییر آدرس IP میتوانید از دستور ()Wifi.config استفاده کنید.
4. در این مرحله برنامهی TCP Client که پیشتر دانلود و نصب کردهاید را داخل تلفن همراه خود باز کنید.
برای ایجاد ارتباط، بر روی گزینهی connect کلیک کنید، سپس در پنجرهی زیر در قسمت Name یک نام دلخواه وارد کرده و سپس آدرس آیپی ماژول ESP و پورت 80 را مطابق تصویر زیر وارد نمایید.
در این آموزش ما از پورت 80 برای سرورESP خود استفاده کردیم، شما میتوانید این پورت را از خط 23ام برنامه تغییردهید.
5. در نهایت برروی گزینه Add کلیک کنید و منتظر بمانید تا ارتباط TCP برقرار و عبارت “Connected” نمایش داده شود.
ارسال دستورات به آردوینو با موبایل
ما در این مرحله نیاز داریم تا برای برقراری ارتباط با ماژول ESP8266 و کنترل آردوینو در شبکه، از دستورات Attention (AT Commands) استفاده نماییم. بنابراین پس از اتصال WiFi موبایل به ماژول ESP-01، دستور زیر را تایپ میکنیم تا یک درخواست به کلاینت TCP ارسال شود:
esp8266: <any AT Commands>
شما میتوانید از جدول زیر، دستورات AT موردنیاز را بهکار ببرید:
نمونهای از کدهایی که میتوانید در این برنامه به کار ببرید:
الایدی داخلی را با دستور زیر روشن کنید:
LEDON
الایدی داخلی را با دستور زیر خاموش کنید:
LEDOFF
و مشاهدهی عبارت زیر در خروجی:
HELLO
توجه:
ESP8266 ،LEDON ،LEDOFF و HELLO از جمله اسامی به کاررفته در این برنامه است و درصورتیکه از نامهای دیگری استفاده کنید با خطای ErrRead روبهرو خواهید شد. ( خط 64 برنامه)
شما میتوانید بسته به منطقی که در کد آردوینو قرارمیدهید، پاسخها را نسبت به آنچه ارسال میکنید، تغییر دهید.
توضیحات کد:
در این بخش ما تکههایی از کد داده شده در رابطه با کنترل آردوینو در شبکه را برای درک بهتر شما از نحوه اجرای آن، توضیح دادهایم:
لطفاً توجه داشته باشید، نسخههای مختلف ماژول ESP ممکن است باودریتهای مختلفی داشته باشند، که از طریق خط 16 برنامه میتوانید باودریت موردنظرخود را تنظیم کنید.
در این قسمت از کد متوجه میشوید که تمامی دستورات ما در تابع ()loop تجزیه و خوانده میشوند.
if(wifiSerial.available()>0){
String message = readWifiSerialMessage();
if(find(message,"esp8266:")){
String result = sendToWifi(message.substring(8,message.length()),responseTime,DEBUG);
if(find(result,"OK"))
sendData("\n"+result);
else
sendData("\nErrRead"); //At command ERROR CODE for Failed Executing statement
}else
if(find(message,"HELLO")){ //receives HELLO from wifi
sendData("\\nHI!"); //arduino says HI
}else if(find(message,"LEDON")){
digitalWrite(13,HIGH);
}else if(find(message,"LEDOFF")){
digitalWrite(13,LOW);
}
else{
sendData("\nErrRead"); //Command ERROR CODE for UNABLE TO READ
}
}
در این قسمت از کد مشاهده میکنید که از تابع find برای تفسیر پیامها استفاده کردهایم و مشخص می کنیم کدام کد به ازای هر پیام توسط آردوینو فراخوانی شود.
اگرمیخواهید با آردوینو ارتباط برقرار کنید و فرمانی را اجرا کنید کافیاست شرط خود را به ازای پیامی که برای آردوینو ارسال میکنید اضافه کرده و کد مربوط به آن را بنویسید. مانند مثال زیر:
if(find(message,"MY CODE")){
// I found 'MY CODE' from received message
// lets do something here
}
if(find(message,"A")){
// I found 'A' from received message
// lets do something here
}
در بخش زیر نیز همانطور که میبینید ما از تابع void sendData(string str) برای برقراری ارتباط با ماژول ESP استفاده کردهایم:
/*
* Name: sendData
* Description: Function used to send string to tcp client using cipsend
* Params:
* Returns: void
*/
void sendData(String str){
String len="";
len+=str.length();
sendToWifi("AT+CIPSEND=0,"+len,responseTime,DEBUG);
delay(100);
sendToWifi(str,responseTime,DEBUG);
delay(100);
sendToWifi("AT+CIPCLOSE=5",responseTime,DEBUG);
}
/*
* Name: find
* Description: Function used to match two string
* Params:
* Returns: true if match else false
*/
boolean find(String string, String value){
if(string.indexOf(value)>=0)
return true;
return false;
}
/*
* Name: readSerialMessage
* Description: Function used to read data from Arduino Serial.
* Params:
* Returns: The response from the Arduino (if there is a reponse)
*/
String readSerialMessage(){
char value[100];
int index_count =0;
while(Serial.available()>0){
value[index_count]=Serial.read();
index_count++;
value[index_count] = '\0'; // Null terminate the string
}
String str(value);
str.trim();
return str;
}
/*
* Name: readWifiSerialMessage
* Description: Function used to read data from ESP8266 Serial.
* Params:
* Returns: The response from the esp8266 (if there is a reponse)
*/
String readWifiSerialMessage(){
char value[100];
int index_count =0;
while(wifiSerial.available()>0){
value[index_count]=wifiSerial.read();
index_count++;
value[index_count] = '\0'; // Null terminate the string
}
String str(value);
str.trim();
return str;
}
/*
* Name: sendToWifi
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendToWifi(String command, const int timeout, boolean debug){
String response = "";
wifiSerial.println(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(wifiSerial.available())
{
// The esp has data so display its output to the serial window
char c = wifiSerial.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.println(response);
}
return response;
}
/*
* Name: sendToUno
* Description: Function used to send data to Arduino.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendToUno(String command, const int timeout, boolean debug){
String response = "";
Serial.println(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(Serial.available())
{
// The esp has data so display its output to the serial window
char c = Serial.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.println(response);
}
return response;
The story
هماکنون که نحوه برقراری ارتباط با Arduino Uno را از طریق Wifi آموختید، میتوانید پروژههای مربوط به اینترنتاشیاء را به سادگی راهاندازی کنید و وسایل الکترونیکی را از راه دور تنها با گوشی موبایل خود، کنترل کنید.
در مراحل پیشرفتهتر این پروژه، اگر با ساخت اپلیکیشنهای تلفن همراه، برنامهها و سرویسهای تحت وب آشنایی داشتهباشید، میتوانید اپلیکیشنهای کلاینتی بسازید که بتوانند درخواستهای TCP را به ماژول ESP ارسال کنند. برخی از این مدل اپلیکیشنها عبارتنداز: Chat Bot ,Push the button app ،Web Control Panel ،Remote Control و… شما همچنین میتوانید باتوجه به میزان مهارت و خلاقیت خود، چند پروژه مانند این را با یکدیگر ترکیب کنید.
امیدواریم از این یادگیری، لذت برده باشید و با موفقیت، تمام مراحل را انجام و نتیجه دلخواه خود را بهدست آورده باشید. چنانچه در مسیر یادگیری این آموزش دچار مشکل شده و سؤالی ذهن شما را به خود درگیر کرده، میتوانید با ارسال پرسش خود یا نظراتتان برای کارشناسان مجموعه روبوایکیو در بخش دیدگاه همین صفحه، پاسخ خود را در اسرع وقت از ما دریافت نمایید.