一文掌握ESP32组建MESH网络

ESP-MESH 简介

“ESP-MESH 是一种构建在 Wi-Fi 协议之上的网络协议。ESP-MESH 允许分布在较大物理区域(室内和室外)的大量设备(称为节点)在单个 WLAN(无线局域网)下互连。ESP-MESH 具有自组织和自修复功能


传统Wi-Fi网络架构

在传统的 Wi-Fi 网络架构中,单个节点(接入点 - 通常是路由器)连接到所有其他节点(站)。每个节点都可以使用接入点相互通信。然而,这仅限于接入点 Wi-Fi 覆盖范围。每个站点都必须位于直接连接到接入点的范围内。ESP-MESH 不会发生这种情况。

ESP-MESH 网络架构

使用 ESP-MESH,节点不需要连接到中央节点。节点负责中继彼此的传输。这允许多个设备分布在较大的物理区域。节点可以自组织并动态地相互通信,以确保数据包到达其最终节点目的地。如果任何节点从网络中删除,它就能够自组织以确保数据包到达目的地。

painlessMesh 库

“painlessMesh 是一个真正的自组织网络,这意味着无需规划、中央控制器或路由器。任何由 1 个或多个节点组成的系统都会自组织成功能齐全的网格。

ESP-MESH 示例(广播消息)

这里使用四个板(两个ESP32和两个ESP8266)进行实验。

代码 – painlessMesh 库基本示例



#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 的消息。

当网格发生变化时,您还应该看到其他消息:当板离开或加入网络时。

使用 ESP-MESH 交换传感器读数

在该例中在 4 个板之间交换交换BME280 传感器的传感器读数。每个板都会收到其他板的读数。

将交换BME280 传感器的传感器读数

所需零件

以下是此示例所需的部件:

ESP32

ESP-MESH 广播传感器读数

该代码读取当前温度、湿度和压力读数并将其广播到网状网络上的所有板。读数以 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

标签:都会   读数   网络   网格   节点   示例   传感器   函数   发生   消息

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top