logo-site-sefid
Search
Close this search box.
Untitled-26

برقراری ارتباط بین ESP32 ،ESP8266 و NodeMCU

نحوه پیکربندی یک شبکه توری ESP با استفاده از IDE آردوینو – ارتباط درمیان و بین ESP32، ESP8266 و NodeMCU

برقراری ارتباط بین ESP32 ،ESP8266 و NodeMCU

اینترنت اشیا ‏(IoT)‏ در طول چند سال گذشته شاهد رشد نمایی بوده‌است در این مقاله نحوه برقراری ارتباط بین ESP32 ،ESP8266 و NodeMCU را خواهیم آموخت. یک مطالعه جدید از سوی شرکت داده‌های بین‌المللی ‏ (IDC)‏ تخمین می‌زند که تقریبا ۴۲ میلیارد دستگاه متصل در سال ۲۰۲۵ وجود خواهد داشت که بیش از ۸۰ زتابایت ‏ (ZB) ‏داده‌ها را تولید می‌کند. با افزایش تعداد دستگاه‌های IoT؛ میزان رشد داده‌ها، همراه با آن، نیاز به ابزارهای برتر شبکه؛ که می‌توانند این بارگذاری را پشتیبانی کنند را افزایش می‌دهد.
با این حال، اگر ما یک میزبان مشترک را در نظر بگیریم (‏مانند یک روتر عمومی)‏، می‌تواند به تعداد محدودی از نودها که دقیق کم‌تر از ۳۲ تا باشد، متصل شود. و با افزایش تعداد دستگاه‌های IoT که می‌توانند در خانه یا صنعت ما باشند، این کافی نیست. در حال حاضر، دو راه‌حل برای این مشکل وجود دارد: اولی استفاده از یک Mesh Router بیرونی است که می‌تواند ارتباطات بسیار بیشتری را در مقایسه با یک پروتکل عمومی کنترل کند، یا ما می‌توانیم از یک پروتکل شبکه به نام شبکه توری استفاده کنیم.
بنابراین در این مقاله، ما یک راه‌اندازی ساده شبکه توری ESP را انجام خواهیم داد که متشکل از چهار دستگاه ESP است که به کمک شبکه توری Wi – Fi با یکدیگر ارتباط برقرار خواهند کرد. و در نهایت، ما قصد داریم یک ESP را به لپ‌تاپ خود متصل کنیم تا داده‌ها را از هر چهار سنسور موجود در شبکه بگیریم. توجه داشته باشید که ما از هر دو برد ESP32 و ESP8266 در این آموزش استفاده خواهیم کرد تا شما بتوانید یک شبکه توری ESP8266 یا شبکه توری ESP32 را با استفاده از همان روش ایجاد کنید.

ESP – MESH چیست و چگونه کار می‌کند؟

با توجه به مستندات رسمی ESP – MESH، این یک شبکه خودگردان و خود ترمیم است به این معنی که شبکه می‌تواند به صورت مستقل ساخته و نگهداری شود.

02-شبکه-توری-چیست-و-چگونه-کار-می کند

شبکه توری گروهی از دستگاه‌های متصل در یک شبکه است که به عنوان یک شبکه واحد عمل می‌کند.ESP – Mesh کاملا متفاوت از راه‌اندازی mesh سنتی است. در یک ESP – Mesh، نود یا یک دستگاه واحد می‌تواند به طور همزمان به دستگاه کناری خود متصل شود. یک نود می‌تواند به چندین نود متصل شود و آن‌ها می‌توانند داده‌ها را از یک‌ نود به نود دیگر منتقل کنند. این فرآیند نه تنها کارآمد است، بلکه اضافی نیز هست. اگر یکی از نودها شکست بخورد؛ داده‌های سایر نودها می‌توانند بدون مشکل به مقصد خود برسند. این امر همچنین امکان دستیابی به اتصال داخلی بدون نیاز به یک‌ نود مرکزی را باز می‌کند، که به طور قابل‌توجهی حوزه پوشش شبکه توری را گسترش می‌دهد. با این ویژگی‌ها، این شبکه کم‌تر مستعد پیوستگی است زیرا تعداد کل نودها در شبکه توسط یک‌نود مرکزی واحد محدود نمی‌شود.
ما به خاطر سادگی تصمیم گرفته‌ایم که از چهار ماژول ESP استفاده کنیم. اما اگر شما در حال ساخت این شبکه هستید، می‌توانید تا جایی که می‌توانید از ESP ها استفاده کنید. برای ساخت شبکه توری، ما قصد داریم از کتابخانه painlessMesh برای آردینو استفاده کنیم که از هر دو ماژول ESP8266 و ESP32 پشتیبانی می‌کند.

اجزای مورد نیاز برای برقراری ارتباط بین ESP32 ،ESP8266 و NodeMCU

لیست مولفه‌های مورد نیاز برای برقراری ارتباط بین ESP32 ،ESP8266 و NodeMCU در زیر آورده شده‌است. برای ساخت این پروژه، من از اجزایی استفاده کرده‌ام که نسبتا عمومی هستند و شما می‌توانید آن‌ها را در فروشگاه محلی سرگرمی خود پیدا کنید.
• NodeMCU(ESP8266) – 2
• 2 – برد ESP32 Dev
• 2 – سنسور BMP280
• 1 – سنسور DHT22
• 1 – سنسور DS18B20
• برد Bread
• کابل USB(‏برای توان و داده)

نمودار مدار ESP Wi-Fi Mesh

طرح کلی نشان‌ داده‌ شده در زیر برای ساخت بخش سخت‌افزار برای ESP8266 و ESP32 بر پایه شبکه توری Wi – Fi استفاده می‌شود.

03-نمودار-مدار-ESP-Wi-Fi-Mesh

برای این مدار، ما دو سنسور BME280 را به برد ESP32 متصل کرده‌ایم، ما یک سنسور DHT22 را به یکی از برد ESP8266 متصل کرده‌ایم، و سنسور DS18B20 را به یک برد ESP8266 دیگر متصل کرده‌ایم. ما قبلا از تمام این سنسورها در پروژه‌های مختلف به صورت جداگانه استفاده کرده‌ایم. در اینجا ما از آن‌ها در بردهای مختلف NodeMCU / ESP32 استفاده خواهیم کرد و سپس آن‌ها را از طریق یک شبکه ESP Mesh به هم متصل خواهیم کرد. یک تصویر برای تنظیمات سخت‌افزاری در زیر نشان‌داده شده‌است.

04-نمودار-مدار-ESP-Wi-Fi-Mesh

برنامه نویسی ESP8266 و ESP32 برای شبکه سازی توری

برای این مقاله، ما قصد داریم از IDE آردوینو در برنامه‌ بردهای ESP32 و ESP8266 استفاده کنیم. در اینجا، ما از کتابخانه painless Mesh برای ساخت شبکه توری استفاده خواهیم کرد. برای نصب کتابخانه، به Sketch-> Include Library-> Manage Libraries بروید و painlessMesh را جستجو کنید. پس از انجام این کار، فقط بر روی نصب کلیک کنید و کتابخانه درIDE آردوینو نصب خواهد شد. همانطور که در تصویر زیر می‌توانید ببینید، زمانی که بر روی نصب کلیک می‌کنید، این کتابخانه از شما می‌خواهد تا توابع بیشتری را نصب کنید. شما باید آن‌ها را برای کار در کتابخانه نصب کنید. برای یادگیری برنامه نویسی میتوانید در کلاسهای آموزش رباتیک صنایع آموزشی چالیک شرکت کنید.

05-برنامه نویسی-ESP8266-و-ESp32-برای-شبکه-توری

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

06-برنامه نویسی-ESP8266-و-ESP32-برای-شبکه-توری

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

آپلود کد در بردESP32 که در آن یک سنسور BME280 متصل شده‌است:

همانطور که می‌توانید در طرح کلی سخت‌افزار ببینید، ما یک سنسور BME280 را متصل کرده‌ایم. برای این کار، شما باید ماکرو را برای سنسور BME _ 280 آنکامنت(uncomment) کنید و یک Node Name یکتا به آن بدهید. در مورد ما، ازNode_1 و Node_2 برای دو برد ESP32 خود استفاده کرده‌ایم که ما سنسور BME280 را به آن متصل کرده‌ایم.

#define BME_280
//#define DHT22
//#define DS18B20
//#define ENABLE_LOG
String nodeName = "NODE_1"; 

آپلود کد در برد ESP8266 که در آن یک سنسور DHT متصل شده‌است:

در یکی از بردهای ESP8266 خود، یک سنسور DHT22 و در یکی دیگر، یک سنسور DS18B20 داریم. برای آپلود کد در برد DHT22، ما باید همان روند را دنبال کنیم. اول، ما ماکرو را برای DHT22 آنکامنت(uncomment) می کنیم و سپس ماکرو را برای BME280 کامنت(commrnt) کرده و کد را در بردی که ما سنسور DHT22 را به آن متصل کرده‌ایم، آپلود می‌کنیم.

//#define BME_280
#define DHT22
//#define DS18B20
//#define ENABLE_LOG
String nodeName = "NODE_3";

تنظیم کد برای برد ESP8266 که در آن یک سنسور DS18B20 متصل است:

این فرآیند برای این برد نیز دقیقا یکسان است. ما ماکرو را برای سنسور DS18B20 آنکامنت(uncomment) کرده و ماکروهای دیگر را کامنت(comment) می کنیم.

//#define BME_280
//#define DHT22
#define DS18B20
//#define ENABLE_LOG
String nodeName = "NODE_3"; 

در نهایت، برای فعال کردن یا غیر فعال کردن دیگر عبارت ها، می‌توانید ماکرویENABLE_LOG را آنکامنت(uncomment) کنید. اکنون که ما درک درستی از چگونگی کارکرد کد داریم، می‌توانیم فراتر رفته و کد را توضیح دهیم.
ما کد خود را با در نظر گرفتن کتابخانه painlessMesh و کتابخانه Arduino_ JSON آغاز خواهیم کرد.

#include <painlessMesh.h>
#include <Arduino_JSON.h>

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

//#define BME_280
#define DHT22
//#define DS18B20
//#define ENABLE_LOG

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

String nodeName = "NODE_4"; // Name needs to be unique
float temp(NAN), hum(NAN), pres(NAN);

از این مرحله به بعد، ما از ماکروهای ifdef # و endif# برای در نظر گرفتن یا حذف بخش‌هایی از کد خود استفاده خواهیم کرد. بخش اول کد برای سنسور BME280 است. همانطور که قبلا گفته شد، ما کار خود را با عبارت ifdef BME _ 280 # آغاز خواهیم کرد. سپس، تمام کتابخانه‌های مورد نیاز برای سنسور BME280 را تعریف می‌کنیم. سنسور BME همچنین از کتابخانه wire استفاده می‌کند، بنابراین ما آن را نیز تعریف می‌کنیم. بعد از آن یک bme شی BME280I2C ایجاد می کنیم. سپس، با استفاده از اپراتور وضوح دامنه، به متغیر class دسترسی پیدا کرده و آن را با عبارت endif به پایان می‌رسانیم.

#ifdef BME_280
#include <BME280I2C.h>
#include <Wire.h>
BME280I2C bme;
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
#endif

همچنین به طور مشابه برای کتابخانه DHT انجام می دهیم. ما با عبارتifdef DHT22 # شروع می‌کنیم که پس از آن DHT قرار دارد. سپس، پین را برای DHT تعریف می‌کنیم و یک نمونه اولیه برای DHT22 اضافه می‌کنیم. پس از آن، ما یک شی را با عبور از عبارات فوق تعریف‌شده ایجاد می‌کنیم. و با عبارت endif# به پایان می رسانیم.

#ifdef DHT22
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#endif

ما همچنین همین کار را برای سنسور DS18B20 انجام می‌دهیم. ما با عبارت ifdef DS18B20 # آغاز می کنیم.
از آنجا که سنسور DS18B20 به کتابخانه OneWire نیاز دارد، ما آن را همراه با کتابخانه Dallhas Temperaturee در نظر می‌گیریم.
سپس، پین را برای سنسور تعریف می کنیم و شی OneWire را با عبور از متغیر پین ایجاد می‌کنیم. سپس آدرس شی OneWire را با ساخت شی جدید DallasTemperature به شی DallasTemperature منتقل می‌کنیم.

#ifdef DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWireBus = 4;
OneWire oneWire(oneWireBus);
DallasTemperature ds18b20(&oneWire);
#endif

سپس، اطلاعات هویتی Wi – Fi را همراه با شماره پرت تعریف می‌کنیم. این شماره پرت و اطلاعات هویتی باید برای تمام نودهای درون شبکه یکسان باشد.

#define   MESH_PREFIX "whateverYouLike"
#define   MESH_PASSWORD "somethingSneaky"
#define   MESH_PORT 5555

سپس، ما سه مورد را ایجاد می‌کنیم. یکی برای Scheduler، یکی برای painlessMesh و دیگری برای JSONVar کتابخانه JSON.

Scheduler userScheduler; // to control your task
painlessMesh  mesh;
JSONVar myVar;

سپس، ما یک task را ایجاد کرده‌ایم که مانند یک رشته است که همیشه اجرا می‌شود و پس از مدتی تابع را فراخوانی می‌کند.task تعریف‌شده در زیر برای ارسال یک پیام انتشار به همه نودها استفاده خواهد شد. این کار فورا سه پارامتر را در بر می‌گیرد. در ابتدا مشخص می‌شود که task تا چه حد تابع را فراخوانی می‌کند، سپس برای عمر task را درخواست می‌کند و در نهایت یک اشاره‌گر به تابع فرخوانی (calling) می‌گیرد.

Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );

بعد از آن، تابع فراخوانی ()sendMessageرا داریم. این تابع، تابع دیگری را فراخوانی می‌کند که رشته‌ای از JSON را برمی گرداند. همان طور که از نامش پیداست، sendMassage task برای ارسال پیام به تمام نودها استفاده می‌شود.

void sendMessage() {
  String msg = construnct_json();
  mesh.sendBroadcast( msg );
  taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}

پس از آن، ما تابع ()receivedCallback خود را داریم. هر وقت یک پیام جدید می‌رسد، این تابع یک فراخوانی می‌گیرد. اگر می‌خواهید کاری با پیام دریافتی انجام دهید، باید این تابع را بهبود بخشید تا کارتان را انجام دهید. این تابع دارای دو آرگومان id نود و پیام به عنوان یک اشاره‌گر است.

void receivedCallback( uint32_t from, String &msg ) {
  Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
}

سپس، تابع ()newConnectionCallback خود را داریم. این تابع هر زمان که یک دستگاه جدید به شبکه اضافه می‌شود یک فراخوانی دریافت می‌کند، و یک عبارت چاپی به نمایشگر سریال می‌فرستد.

void newConnectionCallback(uint32_t nodeId) {
  Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}

در مرحله بعد، ما ()node TimeAdjustedCallbackرا داریم. این تابع callback از تمام نیازهای زمانی مورد نیاز painless mesh مراقبت می‌کند.

void nodeTimeAdjustedCallback(int32_t offset) {
  Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(), offset);
}

سپس، تابع ()setup خود را داریم. در تنظیمات، ما مجموعه را راه‌اندازی کرده و نام نود را چاپ می‌کنیم. این امر مفید است زیرا زمانی که تمام نودها برنامه‌ریزی شدند، ما می‌توانیم به راحتی نودها را با نمایشگر سریال شناسایی کنیم. ما همچنین یک کلاس ()setDebugMsgTypes از شی mesh داریم که هر ERROR پیام‌های STARTUP را ثبت می‌کند. سپس، mesh را با عبور از SSID، گذرواژه و شماره پورت به تابع ()initراه اندازی می‌کنیم. لطفا به خاطر داشته باشید که این توابع همچنین به اشاره‌گر برای Scheduler نیاز دارند تا به درستی کار کند.

Serial.begin(115200);
Serial.println(nodeName);
mesh.setDebugMsgTypes( ERROR | STARTUP );  // set before init() so that you can see startup messages
mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT );

اکنون، ما تمام توابع callback که در بالا مورد بحث قرار دادیم را آغاز خواهیم کرد. هر زمان که یک task خاص برای انجام نیاز باشد، این توابع callback نامیده خواهند شد.

mesh.onReceive(&receivedCallback);
mesh.onNewConnection(&newConnectionCallback);
mesh.onChangedConnections(&changedConnectionCallback);
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);

اکنون ما task را به زمانبندی task اضافه می‌کنیم و آن را با کمک روش ()taskSendMessage.enable فعال می‌کنیم. هنگامی که اجرا می‌شود، task های مختلف به طور همزمان در پس‌زمینه شروع به اجرا می‌کنند.

userScheduler.addTask( taskSendMessage );
taskSendMessage.enable();

سپس، در بخش تنظیمات، همه ifdef و endif متمایز ماکروهایی که برای راه‌اندازی سنسورهای مختلف بسته به نیاز استفاده می‌شوند را داریم. اول، ما سنسور BME280 را پیکربندی خواهیم کرد. کد زیر سنسور BME280 را آغاز کرده و نسخه سنسور را به عنوان سنسور BME280 با نسخه‌های مختلف بررسی می‌کند.

#ifdef BME_280
  Wire.begin();
  while (!bme.begin())
  {
    Serial.println("Could not find BME280 sensor!");
    delay(1000);
  }
  // bme.chipID(); // Deprecated. See chipModel().
  switch (bme.chipModel())
  {
    case BME280::ChipModel_BME280:
      Serial.println("Found BME280 sensor! Success.");
      break;
    case BME280::ChipModel_BMP280:
      Serial.println("Found BMP280 sensor! No Humidity available.");
      break;
    default:
      Serial.println("Found UNKNOWN sensor! Error!");
  }
#endif

در نهایت، ما سنسور DHT22 و DS18B20 را با کمک روش ifdef و #endif پیکربندی کرده‌ایم. و این پایان تابع ()setup را مشخص می‌کند.

#ifdef DHT22
  Serial.println(F("DHTxx Begin!"));
  dht.begin();
#endif
#ifdef DS18B20
  ds18b20.begin();
  Serial.println(F("DS18B20 Begin!"));
#endif

بعد از آن، ما حلقه خود را داریم. در این کد،dose حلقه کار زیادی انجام نمی‌دهد، فقط mesh را به کمک روش ()mesh.update به روز رسانی می‌کند. از تمام taskها مراقبت می کند. اگر این روش به روز رسانی وجود نداشته باشد، این taskها جواب نخواهند داد.

void loop()
{
  mesh.update();
  // construnct_json();
}

سپس، تابع نهایی خود را داریم. این تابع رشته JSON را می‌سازد و آن را به تابع فراخوانی برمی گرداند. در این تابع، ما با فراخوانی روش ()bme.read شروع می‌کنیم و همه متغیرهای از پیش تعریف‌شده را که با مقادیر جدید به روز رسانی می‌شوند، عبور می‌دهیم. سپس، مقدار فشار را به ۱۰۰ تقسیم می‌کنیم زیرا می‌خواهیم آن را به میلی بار تبدیل کنیم. سپس، آرایه JSON خود را تعریف کرده و نام سنسور، نام نود، دما، مقدار فشار را قرار می‌دهیم و مقادیر را با استفاده از تابع ()JSON.stringify برمی گردانیم. در نهایت، یک ifdef دیگر را تعریف می‌کنیم تا پارامترهای log را فعال یا غیر فعال کنیم.

String construnct_json()
{
#ifdef BME_280
  bme.read(pres, temp, hum, tempUnit, presUnit);
  pres = pres / 100;
  myVar["Sensor Type"] = "BME280";
  myVar["Node Name"] = nodeName;
  myVar["Temperature"] = serialized(String(temp, 2));
  myVar["pres"] = serialized(String(pres, 2));
#ifdef ENABLE_LOG
  Serial.println(JSON.stringify(myVar));
#endif
  return JSON.stringify(myVar);
#endif

در نهایت، ما همین کار را برای کد سنسور DHT22 و DS18B20 انجام می‌دهیم.

#ifdef DHT22
  temp = dht.readTemperature();
  hum = dht.readHumidity();
  myVar["Sensor Type"] = "DHT22";
  myVar["Node Name"] = nodeName;
  myVar["Temperature"] = serialized(String(temp));
  myVar["Humidity"] = serialized(String(hum));
#ifdef ENABLE_LOG
  Serial.println(JSON.stringify(myVar));
#endif
  return JSON.stringify(myVar);
#endif
#ifdef DS18B20
  ds18b20.requestTemperatures();
  temp = ds18b20.getTempCByIndex(0);
  myVar["Sensor Type"] = "DS18B20";
  myVar["Node Name"] = nodeName;
  myVar["Temperature"] = serialized(String(temp));
#ifdef ENABLE_LOG
  Serial.println(JSON.stringify(myVar));
#endif
  return JSON.stringify(myVar);
#endif
}

اکنون که فرآیند کدگذاری به پایان رسیده‌است؛ ما در بالا ماکروهای تعریف‌شده را تفسیر می کنیم یا آنکامنتuncomment)) می کنیم؛ برطبق بردمان قصد داریم کد را آپلود کنیم. سپس به هر نود یک نام یکتا می‌دهیم و کد را به سادگی آپلود می‌کنیم. اگر همه چیز درست باشد، کد بدون هیچ خطایی به درستی کامپایل و آپلود خواهد شد.

آزمایش شبکه توری بر پایه ESP8266 و ESP32

07-آزمایش-شبکه-توری-بر-پای-ESP8266-و-ESP32

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

08-آزمایش-شبکه-توری

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

کد

#include <painlessMesh.h>
#include <Arduino_JSON.h>
//#define BME_280
#define DHT22
//#define DS18B20
//#define ENABLE_LOG
String nodeName = "NODE_4"; // Name needs to be unique
float temp(NAN), hum(NAN), pres(NAN);
//########################## Init_BME280 ##########################
#ifdef BME_280
#include <BME280I2C.h>
#include <Wire.h>
BME280I2C bme;
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
#endif
//__________________________ End of _BME280 __________________________
//########################## Init_DHT22 ##########################
#ifdef DHT22
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#endif
//__________________________ End of DHT22 __________________________
//########################## Init_Ds18B20 ##########################
#ifdef DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWireBus = 4;
OneWire oneWire(oneWireBus);
DallasTemperature ds18b20(&oneWire);
#endif
//__________________________ End of DHT22 __________________________
#define   MESH_PREFIX     "whateverYouLike"
#define   MESH_PASSWORD   "somethingSneaky"
#define   MESH_PORT       5555
Scheduler userScheduler; // to control your personal task
painlessMesh  mesh;
JSONVar myVar;
void sendMessage() {
  String msg = construnct_json();
  mesh.sendBroadcast( msg );
  taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}
Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );
// Needed for painless library
void receivedCallback( uint32_t from, String &msg ) {
  Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());
}
void newConnectionCallback(uint32_t nodeId) {
  Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}
void changedConnectionCallback() {
  Serial.printf("Changed connections\n");
}
void nodeTimeAdjustedCallback(int32_t offset) {
  Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(), offset);
}
void setup()
{
  Serial.begin(115200);
  Serial.println(nodeName);
//  mesh.setDebugMsgTypes( ERROR | STARTUP | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
  mesh.setDebugMsgTypes( ERROR | STARTUP );  // set before init() so that you can see startup messages
  mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT );
  mesh.onReceive(&receivedCallback);
  mesh.onNewConnection(&newConnectionCallback);
  mesh.onChangedConnections(&changedConnectionCallback);
  mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
  userScheduler.addTask( taskSendMessage );
  taskSendMessage.enable();
#ifdef BME_280
  Wire.begin();
  while (!bme.begin())
  {
    Serial.println("Could not find BME280 sensor!");
    delay(1000);
  }
  // bme.chipID(); // Deprecated. See chipModel().
  switch (bme.chipModel())
  {
    case BME280::ChipModel_BME280:
      Serial.println("Found BME280 sensor! Success.");
      break;
    case BME280::ChipModel_BMP280:
      Serial.println("Found BMP280 sensor! No Humidity available.");
      break;
    default:
      Serial.println("Found UNKNOWN sensor! Error!");
  }
#endif
#ifdef DHT22
  Serial.println(F("DHTxx test!"));
  dht.begin();
#endif
#ifdef DS18B20
  ds18b20.begin();
#endif
}
void loop()
{
  mesh.update();
  // construnct_json();
}
String construnct_json()
{
#ifdef BME_280
  bme.read(pres, temp, hum, tempUnit, presUnit); // update with new values
  pres = pres / 100;
  myVar["Sensor Type"] = "BME280";
  myVar["Node Name"] = nodeName;
  myVar["Temperature"] = serialized(String(temp, 2)); // serialized need to conver flot values
  myVar["pres"] = serialized(String(pres, 2));// serialized need to conver flot values
#ifdef ENABLE_LOG
  Serial.println(JSON.stringify(myVar)); //stringify converts the arry to a string
#endif
  return JSON.stringify(myVar);
#endif
#ifdef DHT22
  temp = dht.readTemperature();
  hum = dht.readHumidity();
  myVar["Sensor Type"] = "DHT22";
  myVar["Node Name"] = nodeName;
  myVar["Temperature"] = serialized(String(temp));
  myVar["Humidity"] = serialized(String(hum));
#ifdef ENABLE_LOG
  Serial.println(JSON.stringify(myVar));
#endif
  return JSON.stringify(myVar);
#endif
#ifdef DS18B20
  ds18b20.requestTemperatures();
  temp = ds18b20.getTempCByIndex(0);
  myVar["Sensor Type"] = "DS18B20";
  myVar["Node Name"] = nodeName;
  myVar["Temperature"] = serialized(String(temp));
#ifdef ENABLE_LOG
  Serial.println(JSON.stringify(myVar));
#endif
  return JSON.stringify(myVar);
#endif
}

 

رضا قنبری
متخصص آموزش رباتیک

رضا قنبری هستم متخصص آموزش رباتیک با بیش از 10 سال سابقه فعالیت در ایران

این مطلب را به اشتراک بگذارید

ماژول کاهنده

ماژول كاهنده قبل از خواندن مقاله ماژول كاهنده بهتر است در نظر داشته باشید مقالاتی که با عنوان ماژول در سایت قرار گرفته اند از

ماژول تشخیص دود و گاز

ماژول تشخیص دود و گاز قبل از خواندن این مقاله بهتر است در نظر داشته باشید مقالاتی که با عنوان ماژول در سایت قرار گرفته

دیدگاه‌ خود را بنویسید

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