为什么使用 esp-now 可以收到相邻信道的包?esp-now 可靠吗,需要在应用层确认吗?

adadaadadade
Posts: 2
Joined: Wed Jan 17, 2024 2:40 am

为什么使用 esp-now 可以收到相邻信道的包?esp-now 可靠吗,需要在应用层确认吗?

Postby adadaadadade » Wed Jan 17, 2024 2:56 am

使用esp32-s3
版本idfv5.1.2
- 比如一个设备在 2 信道广播另一个设备在 1 3 信道也可以收到该包,并且包来源为信道 2
- esp now 我看文档里面说是有丢包的可能,所以需要在应用层确保可靠吗?那 send_cb 返回的状态是不能确保对方收到数据吗?

ESP_MacChu
Posts: 47
Joined: Tue Nov 21, 2023 7:53 am

Re: 为什么使用 esp-now 可以收到相邻信道的包?esp-now 可靠吗,需要在应用层确认吗?

Postby ESP_MacChu » Mon Jan 22, 2024 12:07 pm

1. 这是由信道特性决定的,相邻信道的数据是有可能被读取到的。如果在程序中配置了辅助信道,比如相邻的信道被用作发送和接收时,分别配置了 WIFI_SECOND_CHAN_ABOVE 和 WIFI_SECOND_CHAN_BELOW,因为信道交叠更会出现所提到的情况。

2. ESP-NOW 没有自动重传。

3. 有关 send_cb:
调用 :cpp:func:`esp_now_send()` 发送 ESP-NOW 数据,调用 :cpp:func:`esp_now_register_send_cb` 注册发送回调函数。如果 MAC 层成功接收到数据,则该函数将返回 `ESP_NOW_SEND_SUCCESS` 事件。否则,它将返回 `ESP_NOW_SEND_FAIL`。ESP-NOW 数据发送失败可能有几种原因,比如目标设备不存在、设备的信道不相同、动作帧在传输过程中丢失等。应用层并不一定可以总能接收到数据。如果需要,应用层可在接收 ESP-NOW 数据时发回一个应答 (ACK) 数据。如果接收 ACK 数据超时,则将重新传输 ESP-NOW 数据。可以为 ESP-NOW 数据设置序列号,从而删除重复的数据。

如果有大量 ESP-NOW 数据要发送,调用 ``esp_now_send()`` 时需注意单次发送的数据不能超过 250 字节。请注意,两个 ESP-NOW 数据包的发送间隔太短可能导致回调函数返回混乱。因此,建议在等到上一次回调函数返回 ACK 后再发送下一个 ESP-NOW 数据。发送回调函数从高优先级的 Wi-Fi 任务中运行。因此,不要在回调函数中执行冗长的操作。相反,将必要的数据发布到队列,并交给优先级较低的任务处理。

adadaadadade
Posts: 2
Joined: Wed Jan 17, 2024 2:40 am

Re: 为什么使用 esp-now 可以收到相邻信道的包?esp-now 可靠吗,需要在应用层确认吗?

Postby adadaadadade » Thu Jan 25, 2024 2:25 am

ESP_MacChu wrote:
Mon Jan 22, 2024 12:07 pm
1. 这是由信道特性决定的,相邻信道的数据是有可能被读取到的。如果在程序中配置了辅助信道,比如相邻的信道被用作发送和接收时,分别配置了 WIFI_SECOND_CHAN_ABOVE 和 WIFI_SECOND_CHAN_BELOW,因为信道交叠更会出现所提到的情况。

2. ESP-NOW 没有自动重传。

3. 有关 send_cb:
调用 :cpp:func:`esp_now_send()` 发送 ESP-NOW 数据,调用 :cpp:func:`esp_now_register_send_cb` 注册发送回调函数。如果 MAC 层成功接收到数据,则该函数将返回 `ESP_NOW_SEND_SUCCESS` 事件。否则,它将返回 `ESP_NOW_SEND_FAIL`。ESP-NOW 数据发送失败可能有几种原因,比如目标设备不存在、设备的信道不相同、动作帧在传输过程中丢失等。应用层并不一定可以总能接收到数据。如果需要,应用层可在接收 ESP-NOW 数据时发回一个应答 (ACK) 数据。如果接收 ACK 数据超时,则将重新传输 ESP-NOW 数据。可以为 ESP-NOW 数据设置序列号,从而删除重复的数据。

如果有大量 ESP-NOW 数据要发送,调用 ``esp_now_send()`` 时需注意单次发送的数据不能超过 250 字节。请注意,两个 ESP-NOW 数据包的发送间隔太短可能导致回调函数返回混乱。因此,建议在等到上一次回调函数返回 ACK 后再发送下一个 ESP-NOW 数据。发送回调函数从高优先级的 Wi-Fi 任务中运行。因此,不要在回调函数中执行冗长的操作。相反,将必要的数据发布到队列,并交给优先级较低的任务处理。
1. 那为什么使用 `esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE)` 设置信道,同时添加的广播 peer channel 也为同一信道的,也还是避免不了收到相邻信道的包,比如我使用4个esp32s3分别在1, 2, 3, 4 向自己所在信道发送广播消息,是可以收到相邻信道的包的。

2. 所以在 `send_cb` 返回状态结果之前不发送其他的包,并且 `send_cb` 返回结果为 success 时是可以认为对方成功获取到数据的吗?还是必须在应用层实现ack才能保证成功接收到数据?

ESP_MacChu
Posts: 47
Joined: Tue Nov 21, 2023 7:53 am

Re: 为什么使用 esp-now 可以收到相邻信道的包?esp-now 可靠吗,需要在应用层确认吗?

Postby ESP_MacChu » Tue Jan 30, 2024 6:47 am

对于问题一,信号发出来不是一个矩形,信道边缘的信号强度比较弱,但当板子接收灵敏度比较高的时候,就能收到。现在 IDF 内部已经有 MR 用于提供途径使得 espnow 仅收到来自自己信道的包了,但是暂时还没有合入,之后会合入的。如果想过滤掉来自相邻信道的包,现在最好的方法是在 payload 里加入一些信息帮助筛选。
对于问题二,send_cb 的返回结果代表有没有发送成功,要想确认对端有没有接收到还是要靠 ACK。

jr-test
Posts: 100
Joined: Mon Aug 23, 2021 3:04 am

Re: 为什么使用 esp-now 可以收到相邻信道的包?esp-now 可靠吗,需要在应用层确认吗?

Postby jr-test » Mon Feb 19, 2024 7:13 am

ESP_MacChu wrote:
Tue Jan 30, 2024 6:47 am
对于问题一,信号发出来不是一个矩形,信道边缘的信号强度比较弱,但当板子接收灵敏度比较高的时候,就能收到。现在 IDF 内部已经有 MR 用于提供途径使得 espnow 仅收到来自自己信道的包了,但是暂时还没有合入,之后会合入的。如果想过滤掉来自相邻信道的包,现在最好的方法是在 payload 里加入一些信息帮助筛选。
对于问题二,send_cb 的返回结果代表有没有发送成功,要想确认对端有没有接收到还是要靠 ACK。
其实esp-now就不是可靠的通信,问题二的接收端接收到发送端的数据,然后给发送端返回一个ACK,那也是会存在发送端收不到接收端的ACK,所以说收到数据和收不到数据很难判定的,esp-now只适合发送控制指令,丢包就补包;如果用来传输数据是不可靠的,或者个人去实现可靠通信的逻辑很难,也复杂。目前学习使用还行,用到项目上就是坑了。是我个人的体会,也希望这个esp-now后面能完善得更好。

Who is online

Users browsing this forum: No registered users and 31 guests