نحوه پیکربندی یک شبکه توری ESP با استفاده از IDE آردوینو – ارتباط درمیان و بین 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، این یک شبکه خودگردان و خود ترمیم است به این معنی که شبکه میتواند به صورت مستقل ساخته و نگهداری شود.
شبکه توری گروهی از دستگاههای متصل در یک شبکه است که به عنوان یک شبکه واحد عمل میکند.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 استفاده میشود.
برای این مدار، ما دو سنسور BME280 را به برد ESP32 متصل کردهایم، ما یک سنسور DHT22 را به یکی از برد ESP8266 متصل کردهایم، و سنسور DS18B20 را به یک برد ESP8266 دیگر متصل کردهایم. ما قبلا از تمام این سنسورها در پروژههای مختلف به صورت جداگانه استفاده کردهایم. در اینجا ما از آنها در بردهای مختلف NodeMCU / ESP32 استفاده خواهیم کرد و سپس آنها را از طریق یک شبکه ESP Mesh به هم متصل خواهیم کرد. یک تصویر برای تنظیمات سختافزاری در زیر نشانداده شدهاست.
برنامه نویسی ESP8266 و ESP32 برای شبکه سازی توری
برای این مقاله، ما قصد داریم از IDE آردوینو در برنامه بردهای ESP32 و ESP8266 استفاده کنیم. در اینجا، ما از کتابخانه painless Mesh برای ساخت شبکه توری استفاده خواهیم کرد. برای نصب کتابخانه، به Sketch-> Include Library-> Manage Libraries بروید و painlessMesh را جستجو کنید. پس از انجام این کار، فقط بر روی نصب کلیک کنید و کتابخانه درIDE آردوینو نصب خواهد شد. همانطور که در تصویر زیر میتوانید ببینید، زمانی که بر روی نصب کلیک میکنید، این کتابخانه از شما میخواهد تا توابع بیشتری را نصب کنید. شما باید آنها را برای کار در کتابخانه نصب کنید. برای یادگیری برنامه نویسی میتوانید در کلاسهای آموزش رباتیک صنایع آموزشی چالیک شرکت کنید.
همانطور که قبلا از بخش سختافزار میدانید، ما از یک سنسور DS18B20، یک سنسور DHT22، و دو سنسور BME استفاده میکنیم. ما باید همه آنها را نصب کنیم، و این کار میتواند به سادگی با روش مدیریت برد انجام شود.
زمانی که تمام کتابخانههای مورد نیاز را دانلود و نصب کردیم، میتوانیم به سمت ایجاد کد برویم.
نکته: توضیح کد که در ادامه میبینید، کد مورد استفاده در هر چهار برد است. ما این کد را طوری طراحی کردهایم که بتوانیم آن را کمی بهبود بخشیم و میتوانیم آن را در هر یک از بردهای 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
تنظیمات آزمایش برای شبکه توری بر پایه ESp8266 و ESP32 در زیر نشانداده شدهاست. همانطور که میتوانید در تصویر بالا ببینید، من توان را به تمام ماژولهای اهداف ویژه متصل کردهام و همچنین میتوانید دادههای خروجی را بر روی صفحه نمایش لپتاپ ببینید. تصویری از پنجرههای نمایشگر سریال در زیر نشانداده شدهاست.
در پنجره بالا، میتوانید ببینید که ما به راحتی دادهها را از هر چهار سنسور دریافت میکنیم.
امیدوارم از این پروژه لذت برده باشید و ساخت پروژه خود را جالب ببینید. اگر سوالی دارید، لطفا آنها را در قسمت نظرات بنویسید.
کد
#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 }