“ESP-MESH 是一种构建在 Wi-Fi 协议之上的网络协议。ESP-MESH 允许分布在较大物理区域(室内和室外)的大量设备(称为节点)在单个 WLAN(无线局域网)下互连。ESP-MESH 具有自组织和自修复功能
在传统的 Wi-Fi 网络架构中,单个节点(接入点 - 通常是路由器)连接到所有其他节点(站)。每个节点都可以使用接入点相互通信。然而,这仅限于接入点 Wi-Fi 覆盖范围。每个站点都必须位于直接连接到接入点的范围内。ESP-MESH 不会发生这种情况。
使用 ESP-MESH,节点不需要连接到中央节点。节点负责中继彼此的传输。这允许多个设备分布在较大的物理区域。节点可以自组织并动态地相互通信,以确保数据包到达其最终节点目的地。如果任何节点从网络中删除,它就能够自组织以确保数据包到达目的地。
“painlessMesh 是一个真正的自组织网络,这意味着无需规划、中央控制器或路由器。任何由 1 个或多个节点组成的系统都会自组织成功能齐全的网格。
这里使用四个板(两个ESP32和两个ESP8266)进行实验。
#include "painlessMesh.h"
#define MESH_PREFIX // "网络名e"
#define MESH_PASSWORD // "密码"
#define MESH_PORT 5555 //服务器运行的 TCP 端口。默认值为 5555。
Scheduler userScheduler; // 调度任务
painlessMesh mesh;
void sendMessage() ; /
Task taskSendMessage( TASK_SECOND * 1 , TASK_FOREVER, &sendMessage );
// 创建一个名为任务发送消息负责致电发信息()只要程序运行,每秒都会运行一次
/* //这发信息()函数向消息网络中的所有节点发送消息(广播)*/
void sendMessage() {
String msg = "Hi from node1";
msg += mesh.getNodeId(); //该消息包含“节点 1 ” 文本后跟板芯片 ID
mesh.sendBroadcast( msg ); //要广播消息,只需使用发送广播()方法上的网对象并传递消息作为参数
taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
//每次发送新消息时,代码都会更改消息之间的间隔(一到五秒)
}
/*创建几个回调函数,当网格上发生特定事件时将调用这些回调函数。
这收到回调()函数打印消息发送者(从)和消息内容(msg.c_str())*/
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("startHere: Received from %u msg=%s
", from, msg.c_str());
}
/*newConnectionCallback()每当有新节点加入网络时,函数就会运行。该函数只是打印新节点的芯片ID*/
void newConnectionCallback(uint32_t nodeId) {
Serial.printf("--> startHere: New Connection, nodeId = %u
", nodeId);
}
/*这改变连接回调()每当网络上的连接发生变化时(当节点加入或离开网络时),函数就会运行*/
void changedConnectionCallback() {
Serial.printf("Changed connections
");
}
/*这节点时间调整回调()函数在网络调整时间时运行,使所有节点同步。它打印偏移量。*/
void nodeTimeAdjustedCallback(int32_t offset) {
Serial.printf("Adjusted time %u. Offset = %d
", mesh.getNodeTime(),offset);
}
void setup() {
Serial.begin(115200);
//选择所需的调试消息类型
//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
mesh.setDebugMsgTypes( ERROR | STARTUP ); //mesh网络配置
//使用之前定义的详细信息初始化网格
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() {
// it will run the user scheduler as well
mesh.update();
}
要保持网格运行,请添加网格.update()到环形().
void loop() {
// it will run the user scheduler as well
mesh.update();
}
这些是节点 1 接收的消息。它接收来自节点 2、3 和 4 的消息。
当网格发生变化时,您还应该看到其他消息:当板离开或加入网络时。
在该例中在 4 个板之间交换交换BME280 传感器的传感器读数。每个板都会收到其他板的读数。
将交换BME280 传感器的传感器读数
以下是此示例所需的部件:
该代码读取当前温度、湿度和压力读数并将其广播到网状网络上的所有板。读数以 JSON 字符串形式发送,其中还包含用于识别发送板的节点号。
#include
#include
#include "painlessMesh.h"
#include
// MESH Details
#define MESH_PREFIX "RNTMESH" //网络名
#define MESH_PASSWORD "MESHpassword" //密码
#define MESH_PORT 5555 //端口
//默认的 I2C 引脚上的 BME 对象
Adafruit_BME280 bme;
//节点号
int nodeNumber = 2;
String readings;
Scheduler userScheduler; // to control your personal task
painlessMesh mesh;
void sendMessage() ; // Prototype so PlatformIO doesn't complain
String getReadings(); // Prototype for sending sensor readings
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);
}
//Init BME280
void initBME(){
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("Received from %u msg=%s
", 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
", nodeId);
}
void changedConnectionCallback() {
Serial.printf("Changed connections
");
}
void nodeTimeAdjustedCallback(int32_t offset) {
Serial.printf("Adjusted time %u. Offset = %d
", mesh.getNodeTime(),offset);
}
void setup() {
Serial.begin(115200);
initBME();
//mesh.setDebugMsgTypes( ERROR | 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();
}
void loop() {
// it will run the user scheduler as well
mesh.update();
}
页面更新:2024-05-27
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号