ESP32C6同时使用ESP-NOW与WiFi Station时通信失败求助
ESP32C6 WiFi Station与ESP-NOW共存问题解决
问题原因
ESP-NOW依赖WiFi物理层通信,要求通信双方必须工作在同一WiFi信道。当Master作为Station连接到AP后,会自动切换到AP所在的信道,但你的代码存在两个关键问题:
- Master在WiFi连接完成前就初始化了ESP-NOW并添加Peer,此时Peer信道设为
0(自动选择),后续WiFi切换信道后,ESP-NOW未同步更新Peer信道 - Slave仅启动WiFi Station但未连接AP,其WiFi信道大概率与Master当前连接的AP信道不匹配,导致无法接收ESP-NOW数据
解决方案
1. 同步ESP-NOW与WiFi信道
在Master成功连接WiFi后,获取当前AP的信道,再初始化ESP-NOW并添加Peer,确保Peer信道与当前WiFi信道完全一致。
2. 调整初始化顺序
将ESP-NOW的初始化和Peer添加操作,放到WiFi连接成功的逻辑之后,避免因信道未确定导致的通信失败。
3. 统一Slave端的WiFi信道
Slave可选择连接同一个AP(自动同步信道),或手动设置WiFi信道与Master连接的AP信道一致。
修改后的关键代码
Master端逻辑调整
修改app_main中Master的初始化流程,等待WiFi连接完成后再处理ESP-NOW:
if (strcmp(Iam, "Master") == 0) { wifi_init_sta(); // 等待WiFi连接完成 // 获取当前连接的AP信道 wifi_ap_record_t ap_info; ESP_ERROR_CHECK(esp_wifi_sta_get_ap_info(&ap_info)); uint8_t current_channel = ap_info.primary; ESP_LOGI(TAG, "Current AP channel: %d", current_channel); espnow_init(); for(int i=0;i<Nsensor;i++) { drt_peer_add_with_channel(slave_mac[i], current_channel); // 传入同步后的信道 } }
修改Peer添加函数
新增支持指定信道的Peer添加函数:
static void drt_peer_add_with_channel(uint8_t *peer_addr, uint8_t channel) { esp_now_peer_info_t *peer = malloc(sizeof(esp_now_peer_info_t)); if (peer==NULL) { ESP_LOGE(TAG, "Malloc peer information fail"); esp_now_deinit(); return; } memset(peer, 0, sizeof(esp_now_peer_info_t)); peer->channel = channel; // 设置为当前WiFi信道 peer->ifidx = ESP_IF_WIFI_STA; peer->encrypt = false; memcpy(peer->peer_addr, peer_addr, ESP_NOW_ETH_ALEN); ESP_ERROR_CHECK(esp_now_add_peer(peer)); free(peer); }
Slave端可选调整
若Slave无需连接外网,可手动设置信道与Master的AP一致:
// 在Slave的WiFi初始化后添加 #define AP_CHANNEL 6 // 替换为你的AP实际信道 ESP_ERROR_CHECK(esp_wifi_set_channel(AP_CHANNEL, WIFI_SECOND_CHAN_NONE));
额外注意事项
- ESP-NOW在WiFi Station模式下,双方的WiFi接口(
ifidx)必须均设置为ESP_IF_WIFI_STA - 若AP信道变更,需通过监听WiFi事件动态更新ESP-NOW Peer的信道
内容的提问来源于stack exchange,提问作者cwbyun
相关产品推荐
相关产品推荐

