乐鑫技术交流
直播中

klysa

12年用户 1223经验值
私信 关注
[问答]

ESP MESH各节点无法互联怎么解决?

最近测试esp-mesh,发现使用例程编译后没两个esp32开发板没办法组网,已经试遍所有办法。
SDK是Arduino 2.0.0 rc1(idf 4.4)。之前用IDF3.3.1测试也是相同的结果。
使用idf 4.4的代码如下(两块开发板刷入相同内容)。

#include #include #include "esp_wifi.h"#include "esp_system.h"#include "esp_event.h"#include "esp_log.h"#include "esp_mesh.h"#include "esp_mesh_internal.h"#include "nvs_flash.h"#include "esp_netif.h"static bool is_mesh_connected = false;static mesh_addr_t mesh_parent_addr;static int mesh_layer = -1;static esp_netif_t *netif_sta = NULL;#define CONFIG_MESH_ROUTE_TABLE_SIZE 50uint8_t g_meshAddr[6] = {0};uint8_t g_deviceId[6] = {0};#define CONFIG_MESH_TOPOLOGY MESH_TOPO_TREE /* MESH_TOPO_TREE / MESH_TOPO_CHAIN */#define CONFIG_MESH_PS_DEV_DUTY 10 /* 1 - 100 */#define CONFIG_MESH_PS_DEV_DUTY_TYPE  MESH_PS_DEVICE_DUTY_REQUEST /* MESH_PS_DEVICE_DUTY_REQUEST / MESH_PS_DEVICE_DUTY_DEMAND */#define CONFIG_MESH_PS_NWK_DUTY 10#define CONFIG_MESH_PS_NWK_DUTY_DURATION  -1#define CONFIG_MESH_PS_NWK_DUTY_RULE  MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE//#define CONFIG_MESH_ENABLE_PSvoid mesh_event_handler(void *arg, esp_event_base_t event_base,                        int32_t event_id, void *event_data){    mesh_addr_t id = {0};    static uint8_t last_layer = 0;    switch(event_id)   {      case MESH_EVENT_STARTED:     {          esp_mesh_get_id(&id);          Serial.printf("ID:%02x:%02x:%02x:%02x:%02x:%02xn", MAC2STR(id.addr));          is_mesh_connected = false;          mesh_layer = esp_mesh_get_layer();      }      break;      case MESH_EVENT_STOPPED:     {          Serial.printf("n");          is_mesh_connected = false;          mesh_layer = esp_mesh_get_layer();      }      break;      case MESH_EVENT_CHILD_CONNECTED:     {          mesh_event_child_connected_t *child_connected = (mesh_event_child_connected_t *)event_data;          Serial.printf("aid:%d, %02x:%02x:%02x:%02x:%02x:%02xn",                   child_connected->aid,                   MAC2STR(child_connected->mac));      }      break;      case MESH_EVENT_CHILD_DISCONNECTED:    {          mesh_event_child_disconnected_t *child_disconnected = (mesh_event_child_disconnected_t *)event_data;          Serial.printf("aid:%d, %02x:%02x:%02x:%02x:%02x:%02xn",                   child_disconnected->aid,                   MAC2STR(child_disconnected->mac));      }      break;      case MESH_EVENT_ROUTING_TABLE_ADD:    {          mesh_event_routing_table_change_t *routing_table = (mesh_event_routing_table_change_t *)event_data;          Serial.printf("add %d, new:%dn",                   routing_table->rt_size_change,                   routing_table->rt_size_new);      }      break;      case MESH_EVENT_ROUTING_TABLE_REMOVE:     {          mesh_event_routing_table_change_t *routing_table = (mesh_event_routing_table_change_t *)event_data;          Serial.printf("remove %d, new:%dn",                   routing_table->rt_size_change,                   routing_table->rt_size_new);      }      break;      case MESH_EVENT_NO_PARENT_FOUND:    {          mesh_event_no_parent_found_t *no_parent = (mesh_event_no_parent_found_t *)event_data;          Serial.printf("scan times:%dn",                   no_parent->scan_times);      }      /* TODO handler for the failure */      break;      case MESH_EVENT_PARENT_CONNECTED:    {          mesh_event_connected_t *connected = (mesh_event_connected_t *)event_data;          esp_mesh_get_id(&id);          mesh_layer = connected->self_layer;          memcpy(&mesh_parent_addr.addr, connected->connected.bssid, 6);          Serial.printf(                   "layer:%d-->%d, parent:%02x:%02x:%02x:%02x:%02x:%02x%s, ID:%02x:%02x:%02x:%02x:%02x:%02xn",                   last_layer, mesh_layer, MAC2STR(mesh_parent_addr.addr),                   esp_mesh_is_root() ? "" :                   (mesh_layer == 2) ? "" : "", MAC2STR(id.addr));          last_layer = mesh_layer;          is_mesh_connected = true;          if(esp_mesh_is_root())       {        // 根节点需要在这里开启DHCP获取IP              esp_netif_dhcpc_start(netif_sta);          }      else      {      }      // 开启2个任务          // -> esp_mesh_comm_p2p_start();               }      break;      case MESH_EVENT_PARENT_DISCONNECTED:    {          mesh_event_disconnected_t *disconnected = (mesh_event_disconnected_t *)event_data;          Serial.printf(                   "reason:%dn",                   disconnected->reason);          is_mesh_connected = false;          mesh_layer = esp_mesh_get_layer();      }      break;      case MESH_EVENT_LAYER_CHANGE:     {          mesh_event_layer_change_t *layer_change = (mesh_event_layer_change_t *)event_data;          mesh_layer = layer_change->new_layer;          Serial.printf("layer:%d-->%d%sn",                   last_layer, mesh_layer,                   esp_mesh_is_root() ? "" :                   (mesh_layer == 2) ? "" : "");          last_layer = mesh_layer;      if(mesh_layer == 1)      {        // 这里1是根节点,意味着节点此时变化为根节点        // 此处可以添加节点切换的用户自定义功能       }      else      {      }      }      break;      case MESH_EVENT_ROOT_ADDRESS:     {          mesh_event_root_address_t *root_addr = (mesh_event_root_address_t *)event_data;            esp_mesh_get_id(&id);                Serial.printf("root address:%02x:%02x:%02x:%02x:%02x:%02x, ID:%02x:%02x:%02x:%02x:%02x:%02xn",                   MAC2STR(root_addr->addr), MAC2STR(id.addr));      // 此处登记自身在路由表中的地址      int route_table_size = 0;      mesh_addr_t route_table[CONFIG_MESH_ROUTE_TABLE_SIZE];      esp_mesh_get_routing_table((mesh_addr_t *) &route_table, CONFIG_MESH_ROUTE_TABLE_SIZE * 6, &route_table_size);            memcpy(g_meshAddr, route_table[0].addr, 6);      Serial.printf("meshAddr:%02x:%02x:%02x:%02x:%02x:%02xn", MAC2STR(g_meshAddr));      // 此处设置默认设备ID      memcpy(g_deviceId, g_meshAddr, 6);      }      break;      case MESH_EVENT_VOTE_STARTED:     {          mesh_event_vote_started_t *vote_started = (mesh_event_vote_started_t *)event_data;          Serial.printf(                   "attempts:%d, reason:%d, rc_addr:%02x:%02x:%02x:%02x:%02x:%02xn",                   vote_started->attempts,                   vote_started->reason,                   MAC2STR(vote_started->rc_addr.addr));      }      break;      case MESH_EVENT_VOTE_STOPPED:     {          Serial.printf("n");          break;      }      case MESH_EVENT_ROOT_SWITCH_REQ:     {          mesh_event_root_switch_req_t *switch_req = (mesh_event_root_switch_req_t *)event_data;          Serial.printf(                   "reason:%d, rc_addr:%02x:%02x:%02x:%02x:%02x:%02xn",                   switch_req->reason,                   MAC2STR( switch_req->rc_addr.addr));      }      break;      case MESH_EVENT_ROOT_SWITCH_ACK:     {          /* new root */          mesh_layer = esp_mesh_get_layer();          esp_mesh_get_parent_bssid(&mesh_parent_addr);          Serial.printf("layer:%d, parent:%02x:%02x:%02x:%02x:%02x:%02xn", mesh_layer, MAC2STR(mesh_parent_addr.addr));      }      break;      case MESH_EVENT_TODS_STATE:     {          mesh_event_toDS_state_t *toDs_state = (mesh_event_toDS_state_t *)event_data;          Serial.printf("state:%dn", *toDs_state);      }      break;      case MESH_EVENT_ROOT_FIXED:     {          mesh_event_root_fixed_t *root_fixed = (mesh_event_root_fixed_t *)event_data;          Serial.printf("%sn",                   root_fixed->is_fixed ? "fixed" : "not fixed");      }      break;      case MESH_EVENT_ROOT_ASKED_YIELD:     {          mesh_event_root_conflict_t *root_conflict = (mesh_event_root_conflict_t *)event_data;          Serial.printf(                   "%02x:%02x:%02x:%02x:%02x:%02x, rssi:%d, capacity:%dn",                   MAC2STR(root_conflict->addr),                   root_conflict->rssi,                   root_conflict->capacity);      }      break;      case MESH_EVENT_CHANNEL_SWITCH:     {          mesh_event_channel_switch_t *channel_switch = (mesh_event_channel_switch_t *)event_data;          Serial.printf("new channel:%dn", channel_switch->channel);      }      break;      case MESH_EVENT_SCAN_DONE:     {          mesh_event_scan_done_t *scan_done = (mesh_event_scan_done_t *)event_data;          Serial.printf("number:%dn",                   scan_done->number);      }      break;      case MESH_EVENT_NETWORK_STATE:     {          mesh_event_network_state_t *network_state = (mesh_event_network_state_t *)event_data;          Serial.printf("is_rootless:%dn",                   network_state->is_rootless);      }      break;      case MESH_EVENT_STOP_RECONNECTION:     {          Serial.printf("n");      }      break;      case MESH_EVENT_FIND_NETWORK:     {          mesh_event_find_network_t *find_network = (mesh_event_find_network_t *)event_data;          Serial.printf("new channel:%d, router BSSID:%02x:%02x:%02x:%02x:%02x:%02xn",                   find_network->channel, MAC2STR(find_network->router_bssid));      }      break;      case MESH_EVENT_ROUTER_SWITCH:     {          mesh_event_router_switch_t *router_switch = (mesh_event_router_switch_t *)event_data;          Serial.printf("new router:%s, channel:%d, %02x:%02x:%02x:%02x:%02x:%02xn",                   router_switch->ssid, router_switch->channel, MAC2STR(router_switch->bssid));      }      break;      default:          Serial.printf("unknown id:%dn", event_id);      break;  }}void ip_event_handler(void *arg, esp_event_base_t event_base,                      int32_t event_id, void *event_data){    ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;    Serial.printf("IP: %d.%d.%d.%dn", IP2STR(&event->ip_info.ip));}#define DEFAULT_MESH_SSID           "aaaaaaaaaa" /* Max=30+1 Min=8+1(Base64编码6字节MAC有8位)*/#define DEFAULT_MESH_PASSWORD       "bbbbbbbbbb" /* Max=60+1 */#define DEFAULT_MESH_CHANNEL        6#define DEFAULT_MESH_MAX_PLAYER     6#define DEFAULT_MESH_AP_PASSWD      "MESH_AP_PASSWORD"#define DEFAULT_MESH_AP_CONNECTIONS 6static const uint8_t MESH_ID[6] = { 0x77, 0x77, 0x77, 0x77, 0x77, 0x77};//static const uint8_t MESH_ID[6] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88};void setup() {  // put your setup code here, to run once:    Serial.begin(115200);    /* 初始化NVS */    nvs_flash_init();    /* 初始化底层TCP/IP堆栈        */    esp_netif_init();      /* 事件初始化*/    esp_event_loop_create_default();  /* 为 Mesh 创建STA和AP模式网络接口(仅保存STA接口供进一步处理),并关闭DHCP服务器和客户端(DHCP客户端只有设备升根节点才启用) */  esp_netif_create_default_wifi_mesh_netifs(&netif_sta, NULL);      /* Wi-Fi 初始化 */    wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();    esp_wifi_init(&config);  /* 注册 IP 事件处理程序 */    esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL);    esp_wifi_set_storage(WIFI_STORAGE_FLASH);    esp_wifi_start();      /* Mesh 初始化 */    esp_mesh_init();  /* 注册 Mesh 事件处理程序 */    esp_event_handler_register(MESH_EVENT, ESP_EVENT_ANY_ID, &mesh_event_handler, NULL);  /*  set mesh topology */    esp_mesh_set_topology(CONFIG_MESH_TOPOLOGY);  /* 设置 Mesh 最大层 */    esp_mesh_set_max_layer(DEFAULT_MESH_MAX_PLAYER);  /* 设置 Mesh 根节点推举百分比(只有达到此阈值才可成为根) */    esp_mesh_set_vote_percentage(1);  // ???    esp_mesh_set_xon_qsize(128);    #ifdef CONFIG_MESH_ENABLE_PS    /* Enable mesh PS function */    esp_mesh_enable_ps();    /* 设置 Mesh AP模式关联过期时间(在AP模式下此时间内未收到某个子节点的任何数据,Mesh将子节点置为不活跃的并分离它) */    esp_mesh_set_ap_assoc_expire(60);    /* better to increase the announce interval to avoid too much management traffic, if a small duty cycle is set. */    esp_mesh_set_announce_interval(600, 3300);#else    /* Disable mesh PS function */    esp_mesh_disable_ps();    esp_mesh_set_ap_assoc_expire(10);#endif  /* Mesh 配置 */  /* 默认启用 Mesh IE 加密 */    mesh_cfg_t cfg;    cfg.crypto_funcs = &g_wifi_default_mesh_crypto_funcs;    /* Mesh ID */    memcpy((uint8_t *) &cfg.mesh_id, MESH_ID, 6);      /* 路由器 */  /* 信道(需与路由器信道匹配)*/    cfg.channel = DEFAULT_MESH_CHANNEL;    // 这里为了方便直接填写了要接入WIFI的SSID和密码    cfg.router.ssid_len = strlen(DEFAULT_MESH_SSID);    strcpy((char*)cfg.router.ssid, DEFAULT_MESH_SSID);    strcpy((char*)cfg.router.password, DEFAULT_MESH_PASSWORD);    /* Mesh softAP */    esp_mesh_set_ap_authmode(WIFI_AUTH_WPA2_PSK);    cfg.mesh_ap.max_connection = DEFAULT_MESH_AP_CONNECTIONS;    strcpy((char*)cfg.mesh_ap.password, DEFAULT_MESH_AP_PASSWD);    esp_mesh_set_config(&cfg);      /* Mesh 启动 */    esp_mesh_start();  #ifdef CONFIG_MESH_ENABLE_PS    /* set the device active duty cycle. (default:10, MESH_PS_DEVICE_DUTY_REQUEST) */    esp_mesh_set_active_duty_cycle(CONFIG_MESH_PS_DEV_DUTY, CONFIG_MESH_PS_DEV_DUTY_TYPE);    /* set the network active duty cycle. (default:10, -1, MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE) */    esp_mesh_set_network_duty_cycle(CONFIG_MESH_PS_NWK_DUTY, CONFIG_MESH_PS_NWK_DUTY_DURATION, CONFIG_MESH_PS_NWK_DUTY_RULE);#endif    Serial.printf("mesh starts successfully, heap:%d, %s<%d>%s, ps:%dn",  esp_get_minimum_free_heap_size(),             esp_mesh_is_root_fixed() ? "root fixed" : "root not fixed",             esp_mesh_get_topology(), esp_mesh_get_topology() ? "(chain)":"(tree)", esp_mesh_is_ps_enabled());             }void loop() {  // put your main code here, to run repeatedly:  //delay(10);  Serial.println(esp_mesh_get_type());  delay(1000);}

运行结果输出以下内容:
setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
mesh starts successfully, heap:106896, root not fixed<0>(tree), ps:0
scan times:60
scan times:60
scan times:60
scan times:60
scan times:60

回帖(1)

张健

2024-6-21 16:52:47
要解决ESP MESH各节点无法互联的问题,我们可以按照以下步骤进行排查和解决:

1. 确保硬件连接正确:首先检查两个ESP32开发板的硬件连接是否正确,确保它们都已连接到电源并正常工作。

2. 检查电源电压:确保两个ESP32开发板的电源电压在正常范围内,以避免电源问题导致无法正常工作。

3. 检查代码:检查代码中是否有错误或遗漏,例如是否正确初始化了ESP MESH库,以及是否正确设置了节点的配置参数。

4. 检查日志输出:在代码中添加日志输出,以便在出现问题时能够快速定位问题所在。例如,可以在初始化ESP MESH库后添加日志输出,以确保库已正确初始化。

5. 检查网络配置:确保两个ESP32开发板的网络配置正确,例如SSID和密码是否一致,以及它们是否都使用了相同的信道。

6. 检查Mesh配置:确保两个ESP32开发板的Mesh配置一致,例如Mesh ID、通道等。

7. 检查编译器和IDE设置:确保使用的编译器和IDE设置正确,例如是否选择了正确的目标硬件平台。

8. 尝试更新SDK:如果问题仍然存在,可以尝试更新ESP-IDF SDK到最新版本,以确保使用的是最新的功能和修复。

9. 检查其他干扰因素:检查周围环境是否有其他干扰因素,例如其他无线设备或信号干扰,这可能会影响ESP MESH的通信。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分