Open anecdata opened 1 year ago
Hello, I was recently playing around with the espnow
module and encountered most of these issues.
However, I found some workarounds and made some examples that are might be worth sharing for anyone who will need to work on these issues or want to use the module thoroughly.
While the send
method may return a 0x3066
or 0x3069
error when broadcasting, it is only does so under some specific conditions:
If you only have the broadcast peer registered, you must to pass it as the peer
parameter in send
for the message to be sent and received without any error being raised.
If you have one broadcast peer and one or more valid non-broadcast peers registered, one of the non-broadcast peers must acknowledge the message. Otherwise an ESP-IDF error will be raised.
Here is an example for these conditions:
For the receiver, use the one below.
It appears that you can change the interface's channel by quickly creating an AP with the desired channel number and stopping it directly after.
The only issue with this approach is that you have to wait for any messages sent to be acknowledged or marked as a failed delivery in the internal callback. If you don't, the peer's target channel appear to be ignored and all messages will be sent on the initial channel.
See espnow.ESPNow.send_success
and espnow.ESPNow.send_failure
.
I was also getting issues when using ESPNow to communicate between a ESP32-S2 and a S3. In all this, I found that the initialization need to be a bit different between them.
For ESP32-S2, the initialization need to be this (see that I am communicating with 2 different ESP32 boards, one with ESP32-S3 and other with ESP32-S2):
# MAC Address value needed for the wireless communication
my_mac_address = [0x68, 0xb6, 0xb3, 0x01, 0xf7, 0xf3]
mac_address_power_switch_board = [0x68, 0xb6, 0xb3, 0x01, 0xf7, 0xf1]
mac_address_motor_board = [0x68, 0xb6, 0xb3, 0x01, 0xf7, 0xf2]
wifi.radio.enabled = True
wifi.radio.mac_address = bytearray(my_mac_address)
wifi.radio.start_ap(ssid="NO_SSID", channel=1)
wifi.radio.stop_ap()
_espnow = ESPNow.ESPNow()
motor = motor_board_espnow.MotorBoard(_espnow, mac_address_motor_board, system_data) # System data object to hold the EBike data
power_switch = power_switch_espnow.PowerSwitch(_espnow, mac_address_power_switch_board, system_data) # System data object to hold the EBike data
For ESP32-S3, the initialization need to be this (see that I am communicating only with a ESP32-S2):
wifi.radio.enabled = True
my_mac_address = [0x68, 0xb6, 0xb3, 0x01, 0xf7, 0xf2]
wifi.radio.mac_address = bytearray(my_mac_address)
# MAC Address value needed for the wireless communication with the display
display_mac_address = [0x68, 0xb6, 0xb3, 0x01, 0xf7, 0xf3]
display = display_espnow.Display(display_mac_address, system_data)
I'm not entirely clear on the distinction, other than the shared _espnow
for the (ESP32-S2) device with two peers. Does this setup not work if the ESP32-S2 and ESP32-S3 are swapped?
Everything is channel=1
, so the AP workaround to set the channel may not be strictly necessary in this specific case.
I'm not entirely clear on the distinction, other than the shared
_espnow
for the (ESP32-S2) device with two peers. Does this setup not work if the ESP32-S2 and ESP32-S3 are swapped?
The only difference is that this code is needed on S2:
wifi.radio.start_ap(ssid="NO_SSID", channel=1)
wifi.radio.stop_ap()
I'm planning to take a look at this and https://github.com/adafruit/circuitpython/issues/9380 . For reference: ( https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/error-codes.html )
ESP_ERR_ESPNOW_INTERNAL (0x306a): Internal error
ESP_ERR_ESPNOW_NOT_FOUND (0x3069): ESPNOW peer is not found
I vaguely recall there's a matrix of things you can and/or cannot do at the same time in relation to wifi, channels, bluetooth, and espnow - I worked it out back in micropython days, so hopefully I can work it out here too.
CircuitPython version
Code/REPL
Code and initial testing commentary here (also some on Discord): https://gist.github.com/anecdata/f46a1d07add5fc60cfbcf42dc7be6528
Behavior
The most limiting issue right now I think is that if peer channel is set to anything except
0
(default; becomes channel 1) or1
, send will result inespidf.IDFError: ESP-NOW error 0x306a
. ESP-NOW should operate on any channel. This also prevents running wifi and ESP-NOW simultaneously unless the AP is on channel 1.A couple of other initial questions or issues after testing ESP-NOW... we can put them into separate issues if warranted:
when encryption is used, RSSI is always returned as 0
ValueError: phy_rate must be 0-42
but should allow up to 54Mbps? 36 is allowed to be set, but 24 is the highest that seems to work between sender and receiver.using broadcast peer address results in
ESP-NOW error 0x3066
on send, not sure if this is intended to be supported right nowESP-NOW error 0x306b
if a peer is added more than oncepackets are limited to 250 bytes, trying to send 251 results in
espidf.IDFError: ESP-NOW error 0x306a
but perhaps there's a friendlier input validation error that can be raised?e = espnow.ESPNow()
results inRuntimeError: Already running
if done more than once, but RTD says it's a Singleton:...also unexpected:
Addendum: Two additional nice-to-have features:
Give user code a way to get the number of messages in the buffer. On PSRAM boards, large buffers can be allocated to accommodate high ESP-NOW traffic. Would be nice for user code to see how well it's keeping up. And how many messages have been lost.
Monitor
might be a good example for these.allow configuring more than the default 7 encrypted pairs (can be up to 17, but trades off with SoftAP). Update: An issue has been filed with Espressif to allow runtime configuration of max encrypted pairs.
Addendum 2: Another issue:
microcontroller.ResetReason.WATCHDOG
numerous times per day.Description
No response
Additional information
No response