В данном руководстве рассмотрим, как работает сетевой протокол ESP-MESH для построения ячеистой топологии на платах ESP32 и ESP8266 NodeMCU. ESP-MESH позволяет нескольким устройствам (нодам) связываться друг с другом в одной беспроводной локальной сети. В этом руководстве мы покажем вам, как работать с ESP-MESH с использованием среды Arduino.
Arduino IDE
Если вы хотите использовать платы ESP32 и ESP8266 с помощью Arduino IDE, у вас должны быть установлены пакеты ESP32 или ESP8266. Найти информацию о том, как установить ESP32 в Arduino IDE вы можете здесь:
Знакомимся с ESP-MESH
Согласно документации Espressif:
«ESP-MESH – это сетевой протокол, построенный на основе протокола Wi-Fi. ESP-MESH позволяет нескольким устройствам (называемым нодами), распределенным по большой области в пространстве, соединяться в рамках одной WLAN (беспроводной локальной сети).
ESP-MESH является самоорганизующейся и самовосстанавливающейся, что означает, что сеть может быть построена и поддерживаться автономно».
Чтобы узнать больше, прочтите официальную документацию ESP-MESH.
Стандартная топология сети Wi-Fi
В топологии сети Wi-Fi нода(точка доступа – обычно маршрутизатор) подключена ко всем остальным нодам (станциям). Каждая нода может связываться друг с другом с помощью точки доступа. Однако это ограничивается зоной покрытия точки Wi-Fi. Каждая станция должна находиться в пределах досягаемости прямого подключения к точке доступа. Для ESP-MESH этого не требуется.
Сетевая топология ESP-MESH
С ESP-MESH нодам не нужно подключаться к центральной ноде, так как они отвечают за ретрансляцию передачи. Это позволяет разнести устройства в пространстве. Ноды могут самоорганизовываться и динамически взаимодействовать друг с другом, чтобы обеспечить доставку пакета до конечного адресата. Если какой-либо узел удаляется из сети, она может самоорганизоваться.
Библиотека painlessMesh
Библиотека painlessMesh позволяет создать ячеистую топологию с ESP8266 или / и ESP32 плат.
Установка painlessMesh
Вы можете установить библиотеку через менеджер библиотек Arduino. Перейдите в Инструменты > Управлять библиотеками , найдите «painlessmesh» и установите библиотеку. Мы используем версию 1.4.5
Должно появиться окно с просьбой установить недостающие библиотеки. Выберите «Установить все».
Если это окно не отображается, вам необходимо установить следующие библиотеки:
- ArduinoJson ( автор: bblanchon )
- TaskScheduler
- ESPAsyncTCP (ESP8266)
- AsyncTCP (ESP32)
Если вы используете PlatformIO , добавьте следующие строки в файл platformio.ini, чтобы добавить библиотеки и изменить скорость монитора порта.
Для ESP32:
monitor_speed = 115200
lib_deps = painlessmesh/painlessMesh @ ^1.4.5
ArduinoJson
arduinoUnity
TaskScheduler
AsyncTCP
Для ESP8266:
monitor_speed = 115200
lib_deps = painlessmesh/painlessMesh @ ^1.4.5
ArduinoJson
TaskScheduler
ESPAsyncTCP
Пример сети ESP-MESH
Прежде, чем начать работу с ESP-MESH, мы поэкспериментируем с библиотекой. В этом примере создается ячеистая топология, в которой все платы передают сообщения всем другим.
Данный пример приведен с использованием четырёх платам (две ESP32 и две ESP8266 ). Код совместим как с платами ESP32, так и с ESP8266.
Пример кода
Скопируйте следующий код в Arduino IDE.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
/*/* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp-mesh-esp32-esp8266-painlessmesh/ This is a simple example that uses the painlessMesh library: https://github.com/gmag11/painlessMesh/blob/master/examples/basic/basic.ino */ #include "painlessMesh.h" #define MESH_PREFIX "whateverYouLike" #define MESH_PASSWORD "somethingSneaky" #define MESH_PORT 5555 Scheduler userScheduler; // для контроля painlessMesh mesh; // метод-заглушка void sendMessage() ; // чтобы PlatformIO работал Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage ); void sendMessage() { String msg = "Hi from node1"; msg += mesh.getNodeId(); mesh.sendBroadcast( msg ); taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 )); } // Требуется для painlessMesh 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); //mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // выбираем типы mesh.setDebugMsgTypes( ERROR | STARTUP ); // установите перед функцией init() чтобы выдавались приветственные сообщения 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(); } void loop() { // она также запустит пользовательский планировщик mesh.update(); } |
Перед загрузкой кода вы можете настроить MESH_PREFIX и переменные MESH_PASSWORD (можно изменить пароль).
Затем рекомендуем вам изменить следующую строку для каждой платы, чтобы было легко идентифицировать ячейку, отправившую сообщение. Например, для ноды 1 измените сообщение следующим образом:
1 |
String msg = "Hi from node 1 "; |
Как работает код?
Подключаем библиотеку painlessMesh.
1 |
#include "painlessMesh.h" |
Настраиваем MESH
MESH_PREFIX – имя сети. Можно указать любое.
1 |
#define MESH_PREFIX "напишите что-нибудь" |
MESH_PASSWORD, как следует из названия, является паролем сети. Вы можете изменить его на что угодно.
1 |
#define MESH_PASSWORD "пароль" |
Все ноды в сети должны использовать одни и те же MESH_PREFIX и MESH_PASSWORD.
MESH_PORT относится к TCP-порту, на котором долна работать ячеистая топология. По умолчанию 5555.
1 |
#define MESH_PORT 5555 |
Планировщик
Рекомендуется избегать использования delay () в коде ячеистой топологии. Чтобы поддерживать сеть, некоторые задачи необходимо выполнять в фоновом режиме. Использование delay () может привести к потере стабильности / нарушению работы сети.
Вместо этого рекомендуется использовать TaskScheduler для выполнения задач, который используется в самой painlessMesh.
Следующая строка создает планировщик с именем userScheduler.
1 |
Scheduler userScheduler; // для управления задачами |
PainlessMesh
Создаём объект с именем mesh для работы сети.
Создаём задачи
Создадим задачу с именем taskSendMessage, отвечающую за вызов функции sendMessage () каждую секунду, пока работает программа.
1 |
Task taskSendMessage (TASK_SECOND * 1, TASK_FOREVER, & sendMessage); |
Отправляем сообщение в сеть
Функция sendMessage () отправляет сообщение всем нодам в сети.
1 2 3 4 5 6 7 8 9 10 11 |
void sendMessage() { String msg = "Hi from node 1"; msg += mesh.getNodeId(); mesh.sendBroadcast( msg ); taskSendMessage.setInterval(random(TASK_SECOND * 1, TASK_SECOND * 5)); }} |
Сообщение содержит текст «Hi from node 1», за которым следует идентификатор микросхемы платы.
1 2 3 |
String msg = "Hi from node 1"; msg += mesh.getNodeId(); |
Чтобы отправить сообщение, используем метод sendBroadcast () для объекта сети и передаём в качестве аргумента сообщение (msg), которое мы хотим отправить.
1 |
mesh.sendBroadcast (msg); |
Каждый раз, когда отправляется сообщение, код изменяет интервал между сообщениями (от одной до пяти секунд).
1 |
taskSendMessage.setInterval (random(TASK_SECOND * 1, TASK_SECOND * 5)); |
Обратные функции в сети
Затем создается несколько обратных функций, которые будут вызываться при возникновении определенных событий в сети.
Функция receiveCallback () выводит имя отправителя сообщения и содержимое сообщения (msg.c_str ()).
1 2 3 4 5 |
void receivedCallback( uint32_t from, String &msg ) { Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str()); } |
Функция newConnectionCallback () выполняется всякий раз, когда к сети подключается новая нода. Эта функция выводит идентификатор платы. Вы можете достаточно легко изменить функцию для выполнения любой другой задачи.
1 2 3 4 5 |
void newConnectionCallback(uint32_t nodeId) { Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId); } |
Функция changedConnectionCallback () вызывается всякий раз, когда кто-то подключается или отключается от сети.
1 2 3 4 5 |
void changedConnectionCallback() { Serial.printf("Changed connections\n"); } |
Функция nodeTimeAdjustedCallback () выполнется, когда сеть изменяет время, и все ноды синхронизируются. Выводит смещение.
1 2 3 4 5 |
void nodeTimeAdjustedCallback(int32_t offset) { Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset); } |
setup()
В setup () запускаем монитор порта.
1 2 3 |
void setup () { Serial.begin (115200); |
Выбираем вид сообщения в окне отладки:
1 2 3 4 5 6 7 |
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // выбираем типы mesh.setDebugMsgTypes( ERROR | STARTUP ); // установите перед функцией init() чтобы выдавались приветственные сообщения Инициализируйте сеть с настройками, определенными ранее. mesh.init (MESH_PREFIX, MESH_PASSWORD, & userScheduler, MESH_PORT); |
Назначаем обратные функции соответствующим событиям.
1 2 3 4 5 6 7 |
mesh.onReceive (& ReceiveCallback); mesh.onNewConnection (& newConnectionCallback); mesh.onChangedConnections (& changedConnectionCallback); mesh.onNodeTimeAdjusted (& nodeTimeAdjustedCallback); |
Наконец, добавляем функцию taskSendMessage в userScheduler. Планировщик отвечает за обработку и выполнение задач в нужное время.
1 |
userScheduler.addTask (taskSendMessage); |
Включаем taskSendMessage, чтобы программа начала отправлять сообщения в сеть.
1 |
taskSendMessage.enable (); |
Чтобы сеть оставалась работающей, добавляем mesh.update () в loop ().
1 2 3 4 5 6 7 |
void loop () { // запустит пользовательский планировщик mesh.update (); } |
Как работает код?
Загрузите код на все платы. Не забудьте изменить сообщение, чтобы легко идентифицировать отправителя.
Когда платы подключены к вашему компьютеру, устанавливаем последовательное соединение с каждой платой. Вы можете использовать монитор порта или программное обеспечение, такое как PuTTY, и открываем несколько окон для всех плат.
Вы должны увидеть, что все платы получают сообщения друг друга. Например, Вот сообщения , полученные первой платой от ячеек 2, 3 и 4.
1 2 3 |
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // выбираем типы mesh.setDebugMsgTypes( ERROR | STARTUP ); // установите перед функцией init() чтобы выдавались приветственные сообщения |
Также должны приходить другие сообщения, когда есть изменения в сети
Обмен показаниями датчиков с помощью ESP-MESH
В следующем примере мы будем обмениваться показаниями датчиков между 4 платами. Каждая плата получает другие показания от других.
В качестве примера мы будем обмениваться показаниями датчика BME280 , но вы можете использовать любой другой.
Требуемые детали
Вот список необходимых деталей:
- 4 платы ESP (ESP32 или ESP8266 )
- 4 BME280
- Макетная плата
- Провода DuPont
Библиотека ArduinoJson
Вам также необходимо установить библиотеку ArduinoJson . Выполните следующие шаги, чтобы установить библиотеку.
- Перейдите в Скетч> Подключить библиотеку > Управлять библиотеками .
- Найдите «ArduinoJson».
- Установите библиотеку.
Мы используем библиотеку ArduinoJson версии 6.15.2.
Если вы используете VS Code с PlatformIO, подключите библиотеки в файле platformio.ini следующим образом:
ESP32
monitor_speed = 115200
lib_deps = painlessmesh/painlessMesh @ ^1.4.5
ArduinoJson
arduinoUnity
AsyncTCP
TaskScheduler
adafruit/Adafruit Unified Sensor @ ^1.1.4
adafruit/Adafruit BME280 Library @ ^2.1.2
arduino-libraries/Arduino_JSON @ ^0.1.0
ESP8266
monitor_speed = 115200
lib_deps = painlessmesh/painlessMesh @ ^1.4.5
ArduinoJson
TaskScheduler
ESPAsyncTCP
adafruit/Adafruit Unified Sensor @ ^1.1.4
adafruit/Adafruit BME280 Library @ ^2.1.2
arduino-libraries/Arduino_JSON @ ^0.1.0
Принципиальная схема
Подключите датчик BME280 к контактам I2C ESP32 или ESP8266 как показано на следующих схемах.
ESP 32
ESP8266 NodeMCU
Код для обмена показаниями датчиков
Загрузите следующий код на платы. Этот код считывает и передает текущие показания температуры, влажности и давления на все платы в ячеистой сети. Показания отправляются в виде строки JSON, которая также содержит номер узла для идентификации платы отправителя.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
/* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp-mesh-esp32-esp8266-painlessmesh/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. */ #include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #include "painlessMesh.h" #include <Arduino_JSON.h> // настройки MESH #define MESH_PREFIX "RNTMESH" //введите имя #define MESH_PASSWORD "MESHpassword" //и пароль #define MESH_PORT 5555 //порт по умолчанию //создаем объект BME Adafruit_BME280 bme; //номер ноды int nodeNumber = 2; //Строка, которую будем отправлять другим нодам String readings; Scheduler userScheduler; painlessMesh mesh; // метод-заглушка void sendMessage() ; // благодаря ему PlatformIO будет работать String getReadings(); // получение показаний датчика //Создаем задачи для отправки сообщений и получения показаний Task taskSendMessage(TASK_SECOND * 5 , TASK_FOREVER, &sendMessage); String getReadings () { JSONVar jsonReadings; jsonReadings["node"] = nodeNumber; jsonReadings["temp"] = bme.readTemperature(); jsonReadings["hum"] = bme.readHumidity(); jsonReadings["pres"] = bme.readPressure()/100.0F; readings = JSON.stringify(jsonReadings); return readings; } void sendMessage () { String msg = getReadings(); mesh.sendBroadcast(msg); } //Запускаем BME280 void initBME(){ if (!bme.begin(0x76)) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1); } } // Нужно для работы библиотеки painlessMesh void receivedCallback( uint32_t from, String &msg ) { Serial.printf("Received from %u msg=%s\n", from, msg.c_str()); JSONVar myObject = JSON.parse(msg.c_str()); int node = myObject["node"]; double temp = myObject["temp"]; double hum = myObject["hum"]; double pres = myObject["pres"]; Serial.print("Node: "); Serial.println(node); Serial.print("Temperature: "); Serial.print(temp); Serial.println(" C"); Serial.print("Humidity: "); Serial.print(hum); Serial.println(" %"); Serial.print("Pressure: "); Serial.print(pres); Serial.println(" hpa"); } void newConnectionCallback(uint32_t nodeId) { Serial.printf("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); initBME(); //mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // выбираем типы mesh.setDebugMsgTypes( ERROR | STARTUP ); // установите перед функцией init() чтобы выдавались приветственные сообщения 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(); } void loop() { // функция также запустит планировщик mesh.update(); } |
Код совместим как с платами ESP32, так и с ESP8266.
Как работает код?
Подключаем необходимые библиотеки: Adafruit_Sensor и Adafruit_BME280 для взаимодействия с датчиком BME280; библиотека painlessMesh для работы сети и Arduino_JSON для создания и обработки строк JSON.
1 2 3 4 5 6 7 |
#include <Adafruit_Sensor.h> #include <Adafruit_BME280.h> #include "painlessMesh.h" #include <Arduino_JSON.h> |
Вставьте данные сети в следующие строки.
1 2 3 4 5 |
#define MESH_PREFIX "RNTMESH" // имя MESH #define MESH_PASSWORD "MESHpassword" // пароль #define MESH_PORT 5555 // порт по умолчанию |
Создаём объект Adafruit_BME280 с именем bme на выводах ESP32 или ESP8266 по умолчанию.
1 |
Adafruit_BME280 bme; |
В переменную nodeNumber пишем номер ноды платы. Номер должен быть уникальным.
1 |
int nodeNumber = 2; |
Переменная readings будет использоваться для сохранения показаний.
Чтения строк;
Следующая строка создает планировщик с именем userScheduler.
1 |
Scheduler userScheduler; |
Создаём задачу с именем taskSendMessage, отвечающую за вызов функции sendMessage () каждые пять секунд.
1 |
Task taskSendMessage (TASK_SECOND * 5, TASK_FOREVER и sendMessage); |
Функция getReadings () получает показания температуры, влажности и давления от датчика BME280 и объединяет всю информацию, включая номер ноды, в переменной jsonReadings.
1 2 3 4 5 6 7 8 9 |
JSONVar jsonReadings; jsonReadings["node"] = nodeNumber; jsonReadings["temp"] = bme.readTemperature(); jsonReadings["hum"] = bme.readHumidity(); jsonReadings["pres"] = bme.readPressure()/100.0F; |
В следующей строке показана структура переменной jsonReadings с произвольными значениями.
1 2 3 4 5 6 7 8 9 10 11 |
{ "node":2, "temperature":24.51, "humidity":52.01, "pressure":1005.21 } |
Затем значения переменной jsonReadings преобразуется в строку JSON с помощью метода stringify () и сохраняется в переменной readings.
1 2 3 |
readings = JSON.stringify(jsonReadings); return readings; |
Функция sendMessage () отправляет строку JSON с показаниями и номером ноды (getReadings ()) всем нодам в сети.
1 2 3 4 5 6 7 |
void sendMessage () { String msg = getReadings(); mesh.sendBroadcast(msg); } |
Функция initBME () инициализирует датчик BME280.
1 2 3 4 5 6 7 8 9 10 11 |
void initBME(){ if (!bme.begin(0x76)) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1); } } |
Затем создается несколько обратных функций, которые вызываются, когда происходит какое-либо событие в сети.
Функция receiveCallback () выводит отправителя сообщения и содержимое сообщения (msg.c_str ()).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void receivedCallback( uint32_t from, String &msg ) { Serial.printf("startHere: Received from %u msg=%s\n", from, msg.c_str());Сообщение приходит в формате JSON, поэтому мы можем получить доступ к переменным следующим образом: JSONVar myObject = JSON.parse(msg.c_str()); int node = myObject["node"]; double temp = myObject["temp"]; double hum = myObject["hum"]; double pres = myObject["pres"]; |
Наконец, выводим все на мониторе порта.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Serial.print("Node: "); Serial.println(node); Serial.print("Temperature: "); Serial.print(temp); Serial.println(" C"); Serial.print("Humidity: "); Serial.print(hum); Serial.println(" %"); Serial.print("Pressure: "); Serial.print(pres); Serial.println(" hpa"); |
Функция newConnectionCallback () запускается всякий раз, когда к сети подключается новая нода. Эта функция выводит идентификатор ноды.
1 2 3 4 5 |
void newConnectionCallback (uint32_t nodeId) { Serial.printf ("-> startHere: новое соединение, nodeId =% u \ n", nodeId); } |
Функция changedConnectionCallback () запускается всякий раз, когда соединение изменяется в сети (когда узел присоединяется к сети или покидает ее).
1 2 3 4 5 |
void changedConnectionCallback () { Serial.printf ("Изменены соединения \ n"); } |
Функция nodeTimeAdjustedCallback () запускается, когда сеть регулирует время, так что все узлы синхронизируются. Печатает смещение.
1 2 3 4 5 |
void nodeTimeAdjustedCallback(int32_t offset) { Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset); } |
В setup () запускаем монитор порта.
1 2 3 |
void setup () { Serial.begin (115200); |
Вызываем функцию initBME (), чтобы инициализировать датчик BME280.
1 |
initBME (); |
Выбираем желаемые типы отладочного сообщения:
1 2 3 4 5 |
//mesh.setDebugMsgTypes (ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE); mesh.setDebugMsgTypes (ОШИБКА | ЗАПУСК); // устанавливаем перед init (), чтобы вы могли видеть сообщения запуска |
Инициализируйте сетку с деталями, определенными ранее.
1 |
mesh.init (MESH_PREFIX, MESH_PASSWORD, & userScheduler, MESH_PORT); |
Укажите для всех обратных функций события, с которыми они связаны.
1 2 3 4 5 6 7 |
mesh.onReceive (& ReceiveCallback); mesh.onNewConnection (& newConnectionCallback); mesh.onChangedConnections (& changedConnectionCallback); mesh.onNodeTimeAdjusted (& nodeTimeAdjustedCallback); |
Наконец, добавьте функцию taskSendMessage в userScheduler. Планировщик отвечает за обработку и выполнение задач в нужное время.
1 |
userScheduler.addTask (taskSendMessage); |
Включите taskSendMessage, чтобы программа начала отправлять сообщения в сеть.
1 |
taskSendMessage.enable (); |
Чтобы сеть оставалась работающей, добавьте mesh.update () в loop ().
1 2 3 4 5 6 7 |
void loop () { // он также запустит пользовательский планировщик mesh.update (); } |
Демонстрация
После загрузки кода на все платы вы должны увидеть, что каждая плата получает сообщения от других.
На следующем скриншоте показаны сообщения, полученные нодой 1. Он получает показания датчиков от нод 2, 3 и 4.
Заключение
Мы надеемся, что вам понравилось это краткое введение в основы работы сетевого протокола ESP-MESH. Вы можете ознакомиться более подробно с библиотекой painlessMesh для изучения дополнительных примеров.
Спасибо за чтение
Вопросы по прошивке и работе с кодом лучше писать напрямую автору в комментариях к статье (на англ. языке)
4 комментария. Оставить новый
А как еще и подключить их к роутеру одновременно?
А зачем их к роутеру одновременно подключать?
Стас, привет ! Работаешь с МESH сетями ? Меня заинтересовала Твоя библиотека, которая недоступна в GetHab
Слишком нестабильная библиотека. Есть лучше. https://github.com/aZholtikov/ZHMeshNetwork.