آموزش Espآموزش ESP32آموزش اینترنت اشیا

ارتباط بین دو ESP32 با پروتکل ESP-NOW

روش های مختلفی وجود دارد که زمان ایجاد ارتباط بین دو برد ESP32 میتوانید سراغ آنها بروید اما شاید این سوال ذهنتان را درگیر کرده باشد که مناسب ترین روش کدام است؟ کدام روش همیشه در دسترس است و میتواند در ایجاد ارتباط بین چندین برد مورد استفاده قرار بگیرید؟ در ادامه یکی از کاربردی روش ها را معرفی کرده ایم.

در این مقاله آموزشی میخواهیم نحوه اتصال دو برد ESP32 از طریق پروتکل ارتباطی ESP-NOW را بررسی کنیم. به سادگی میتوانید اطلاعات سنسورها را بخوانید و در فضای باز تا فاصله 200 متر دیتا را انتقال دهید، لطفا با ما همراه باشید.

ESP-NOW چیست؟

ESP-NOW یک پروتکل ارتباطی بی سیم است که توسط Espressif توسعه داده شده و اغلب برای انتقال بسته های کوچک و کمتر از 250 بایت مورد استفاده قرار میگیرد. به کمک این پروتکل امکان اتصال چندین دستگاه وجود دارد و بدون استفاده از شبکه Wi-Fi با هم در ارتباط خواهند بود.

ESP-NOW چیست؟

به کمک این پروتکل ارتباطی سریع میتوانید اطلاعات کوچک و اغلب تا 250 بایت را بین بردهای ESP32 انتقال دهید. این روش بسیار کاربردی امکان ارتباط یک طرفه یا دوطرفه و در ترتیب های مختلف را فراهم کرده است.

با ما همراه باشید، در انتهای این مقاله آموزشی میتوانید بردهای ESP32 خود را به یکدیگر متصل کنید.

ارتباط دو برد ESP32

بررسی سریع پروژه

در تصویر زیر به صورت خلاصه یک نمای کلی از پروژه آورده شده است:

شماتیک ارتباط دو ESP32

  • در این پروژه از دو برد ESP32 استفاده شده است. از نمایشگر OLED و سنسور BME280 نیز استفاده شده است که در تصویر بالا میتوانید این قطعات را مشاهده کنید.
  • هر برد ESP32 دما، رطوبت و فشار را از طریق سنسورهای متصل شده دریافت میکند.
  • دیتای دریافت شده توسط سنسور، از طریق ESP32 به ماژول دیگر ارسال خواهد شد.
  • پس از ارسال مقادیر خوانده شده، در صورتی که دیتا به درستی منتقل شده باشد، OLED یک پیام موفقیت را نمایش خواهد داد.
  • برد ESP32 برای ارسال موفقیت آمیز دیتا لازم است آدرس MAC برد دیگر را در اختیار داشته باشد.

در این پروژه ما ارتباط دو طرفه بین دو برد را آموزش داده ایم اما این امکان را دارید که تعداد بردها را افزایش دهید و بین همه این بردها ارتباط برقرار کنید.

پیش نیازهای انجام پروژه

قبل از ادامه این پروژه، حتما پیش نیازهای زیر را بررسی کنید.

نصب ESP32 در آردوینو

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

نصب کتابخانه های مورد نیاز

در ادامه به کتابخانه های مختلف نیاز دارید و لازم است آنها را در محیط توسعه آردوینو نصب کرده باشید. کافی است کامپایلر آردوینو را باز کنید و از طریق Sketch، Include Library و Manage Libraries نام این کتابخانه ها را جستجو کنید. به این ترتیب میتوانید آنها را نصب کنید و در برنامه نویسی از آن استفاده کنید.

  • کتابخانه های OLED:Adafruit_SSD1306 library و Adafruit_GFX library
  • کتابخانه های BME280: Adafruit_BME280 library و Adafruit Unified

قطعات مورد نیاز

برای پیاده سازی پروژه به قطعات زیر نیاز خواهید داشت:

  • 2 عدد برد توسعه ESP32
  • 2 عدد سنسور BME280
  • 2 عدد نمایشگر OLED 0.96
  • برد بورد
  • سیم جامپر

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

اگر در مورد این مطلب سوالی دارید در قسمت نظرات بپرسید

دریافت آدرس MAC بردها

برای اینکه دیتا را به برد ESP32 انتقال دهیم، باید آدرس MAC آن را بدانیم. هر برد آدرس منحصر به فرد خود را دارد و البته که میتوانید آن آدرس را نیز تغییر داد.

برای دریافت آدرس MAC کافی است کد زیر را در بردها آپلود کنید:

#include "WiFi.h"
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA);
Serial.println(WiFi.macAddress());
}
void loop(){
}

پس از اینکه کد روی برد ESP32 آپلود شد، باید دکمه RST/EN را فشار دهید تا سریال مانیتور نرم افزار آدرس مورد نظر را نمایش دهید.

مک آدرس برد ESP32

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

یادداشت MAC آدرس برد وای فای ESP32

شماتیک مدار اتصال دو برد ESP32

در ادامه باید نمایشگر OLED و سنسور BME280 را به برد ESP32 متصل کنید. البته در این پروژه از دو برد، دو نمایشگر و دو سنسور استفاده شده است که نحوه آنها به شکل زیر است:

شماتیک مدار اتصال دو برد ESP32

برای اتصال سنسور BME280 به برد میتوانید از جدول زیر استفاده کنید:

BME280 ESP32
VIN 3.3V
GND GND
SCL GPIO 22
SDA GPIO 21

برای اتصال نمایشگر اولد به برد ESP32 میتوانید از جدول زیر استفاده کنید:

OLED Display ESP32
GND GND
VCC VIN
SCL GPIO 22
SDA GPIO 21

کدنویسی پروژه

در انتها سراغ کدنویسی پروژه اتصال دو برد ESP32 میرویم و هر دو برد را راه اندازی میکنیم. کد کامل در فایل دانلودی انتهای صفحه قرار داده شده است. در اینجا قسمت های مختلف کد را توضیح میدهیم. با مطالعه ادامه این آموزش متوجه خواهید شد که هر بخش از کدنویسی چه عملکردی دارد و چه کاری انجام میدهد.

همانطور که اشاره شد در این پروژه از پروتکل ارتباطی ESP-NOW استفاده شده است و قبل از هرچیز باید کتابخانه های زیر به پروژه اضافه شود.

#include <esp_now.h>
#include <WiFi.h>

در خط بعدی آدرس MAC برد گیرنده را وارد کنید:

uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};

پارامترهای خوانده شده توسط سنسور BME280 شامل دما، رطوبت و فشار در متغیرهای زیر ذخیره میشود. مقادیر خوانده شده به ESP32 دیگر ارسال میگردد. این متغیرها شامل موارد زیر است:

float temperature;
float humidity;
float pressure;

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

float incomingTemp;
float incomingHum;
float incomingPres;

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

String success;

در ساختار زیر مقادیر دما، رطوبت و فشار را ذخیره کرده ایم.

typedef struct struct_message {
float temp;
float hum;
float pres;
} struct_message;

این Struct به دو صورت ایجاد شده که یکی از آنها مقادیر خوانده شده توسط سنسور را ذخیره میکند و مورد دوم مقادیر دریافت شده از برد ESP32 دوم را نگهداری میکند که به صورت زیر است:

ساختار “BME280Readings” جهت ذخیره سازی پارامترهای خوانده شده توسط سنسور ایجاد شده است.

struct_message BME280Readings;

ساختار “incomingReadings” داده های دریافتی از برد دیگر را ذخیره می کند.

struct_message incomingReadings;

برای ذخیره سازی دیتاهای همتا (peer) یک متغیر از نوع “esp_now_peer_info_t” ایجاد کرده ایم.

esp_now_peer_info_t peerInfo;

سپس دو تابع کال بک تعریف کرده ایم که یکی از این توابع زمان ارسال داده و دیگری زمان دریافت داده فراخوانی میشود.

تابع کال بک OnDataSent()

این تابع زمان دریافت دیتای جدید فراخوانی خواهد شد. ممکن است پیام با موفقیت تحویل داده شود یا خیر، در هر صورت این تابع به سادگی پرینت خواهد شد. در واقع اگر ارسال پیام موفقیت آمیز باشد متغیر وضعیت عدد 0 را برمیگرداند و سپس پیام Delivery Success روی نمایشگر اولد ایجاد میشود.

Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status ==0) {
success = "Delivery Success :)";
}

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

else {
success = "Delivery Fail :(";
}

تابع کال بک OnDataRecv()

این تابع زمانی که دیتای جدید به برد ESP32 ارسال شود، فراخوانی خواهد شد.

void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {

دیتای جدید در ساختار incomingReadings که قبلا ایجاد کرده ایم ذخیره میشود.

memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));

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

Serial.print("Bytes received: ");
Serial.println(len);

زمانی که پارامترهای ارسالی خوانده شد، آنها را در ساختار از قبل ایجاد شده ذخیره میکنیم. برای اینکه پارامتر دما را از ساختار incomingReadings دریافت کنیم، کافی است incomingReadings.temp را کال کنیم که به صورت زیر است:

incomingTemp = incomingReadings.temp;

برای دریافت دیگر متغیرها نیز به همین صورت عمل میکنیم:

incomingHum = incomingReadings.hum;
incomingPres = incomingReadings.pres;

آشنایی با setup()

در بخش setup() باید ESP-NOW را مقدار دهی اولیه کنیم:

if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}

سپس رجیستر مربوط به تابع کال بک OnDataSent را انجام میدهیم:

esp_now_register_send_cb(OnDataSent);

برای اینکه دیتا را به برد دیگر ارسال کنیم ،لازم است آنها را به عنوان Peer جفت کنیم. خطوط زیر مربوط به رجیستر و اضافه کردن یک همتا (Peer) جدید است:

memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false; // Add peer 
if (esp_now_add_peer(&peerInfo) != ESP_OK){ 
  Serial.println("Failed to add peer");
  return;
 }

سپس رجیستر مربوط به تابع کال بک OnDataRecv را انجام میدهیم:

esp_now_register_recv_cb(OnDataRecv);

آشنایی با بخش Loop()

در حلقه Loop() تابع getReadings() که وظیفه دارد دیتای سنسورها را بخواند، را کال میکنیم. پس از اینکه مقادیر مورد نظر دریافت شد لازم است ساختار BME280Reading را آپدیت کنیم. این کار توسط کدهای زیر انجام میشود:

BME280Readings.temp = temperature;
BME280Readings.hum = humidity;
BME280Readings.pres = pressure;

در ادامه باید ساختار BME280Readings که حاوی مقادیر خوانده شده از سنسور است را از طریق پروتکل ارتباطی ESP-NOW به برد دیگر ارسال کنیم.

esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings)); 
if (result == ESP_OK) { 
  Serial.println("Sent with success");
} 
else { 
  Serial.println("Error sending the data");
} 

در انتها تابع updateDisplay() را کال میکنیم تا تا نمایشگر اولد آپدیت شود و پارامترهای دریافت شده از برد ESP32 دیگر را نمایش دهد.

updateDisplay();

حلقه لوپ هر 10 ثانیه اجرا خواهد شد.

شاید در مورد کدنویسی بخش های مربوط به OLED و BME280 ابهام داشته باشید، ما در این مطلب آموزشی به توضیح در مورد پروتکل ارتباطی ESP-NOW و ارتباط بین دو برد ESP32 بسنده کرده ایم. در صورتی که سوالات مختلف ذهنتان را درگیر کرده است، با صرف کمی وقت یا استفاده از ابزارهای مختلف میتوانید در مورد دیگر بخش های کد اطلاع کسب کنید.

با این وجود، توجه داشته باشید که به کدنویسی به صورت کامل دسترسی دارید و به سادگی میتوانید از آن در پروژه های خود استفاده کنید. حالا که با کدنویسی های پروژه آشنا شدید، کافی است تغییرات لازم (آدرس ها) را روی کدهای خود اعمال کنید، کدها را روی برد ESP32 خود آپلود کنید و خروجی پروژه را مشاهده کنید.

مشاهده نتیجه

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

ارتباط بین دو ESP32

در تصویر بالا میتوانید عملکرد برد را مشاهده کنید. همانطور که انتظار میرود پروژه به درستی کار میکند:

فاصله ارتباطی ESP32

ما به صورت عملی فاصله بین این دو برد را آزمایش کردیم و متوجه شدیم که در فضای باز بین دو برد ESP32 با فاصله 220 متر میتوانیم یک ارتباط پایدار داشته باشیم. البته که آنتن برد ESP32 در این آزمایش روبروی یکدیگر قرار گرفته بودند.

تصویر فاصله دو برد

جمع بندی

در این مطلب آموزشی به این موضوع پرداختیم که چطور بین دو برد ESP32 ارتباط دوطرفه ایجاد کنیم. همانطور که اشاره شد روش های مختلف برای این کار وجود دارد که استفاده از پروتکل ارتباطی ESP-NOW یکی از ارزان ترین و مناسب ترین روش های موجود به شمار میرود. به کمک این ارتباطی میتوانید دیتاهای حداکثر 250 بایتی را ارسال کنید و بین تعداد زیادی برد ESP32 ارتباط پایدار برقرار کنید.

امیدواریم این مقاله مورد توجه شما قرار گرفته باشد و به شما در ایجاد ارتباط بین دو برد ESP32 کمک کرده باشد. از اینکه تا انتها با ما همراه بودید از شما متشکریم.

موارد موجود در فایل : سورس کامل

نویسنده این مطلب: احسان اسمعیل پور

محتوا نویس حیطه الکترونیک :) علاقه مند به یادگیری و نوشتن!

Ehsan79es@yahoo.com

4.2 (5 نفر)

برای دریافت مطالب جدید کانال تلگرام یا پیج اینستاگرام ما را دنبال کنید.

محمد رحیمی

محمد رحیمی هستم. سعی میکنم در آیرنکس مطالب مفید قرار بدهم. سوالات مربوط به این مطلب را در قسمت نظرات همین مطلب اعلام کنید. سعی میکنم در اسرع وقت به نظرات شما پاسخ بدهم.

5 نظر

  1. سلام ممنون
    اگه مک آدرس رو کلا بصورت 0:0:0:0:0 نشون بده مشکل از چی می تونه باشه ؟

  2. سلام. اگر امکانش هست کتابخانه esp_now را بابت دانلود قرار بدین.

  3. سلام امکانش هست پروژه ای انجام بدین که تصویر esp32 cam رو به صورت زنده در یک ماژول esp از طریق وای فای پخش کنه ؟

  4. با سلام درون فایل های سورس هیچی نیست و فایل txt خالی است با حجم 1کیلو بایت

    1. سلام عزیز
      با تشکر از اطلاع رسانی شما، تصحیح شد

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *