espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.28k stars 7.35k forks source link

unicast ESP-NOW works in SoftAP but stops working when actually connected to an AP #8912

Open goatzillax opened 9 months ago

goatzillax commented 9 months ago

Board

Wemos ESP32-C3

Device Description

no other hardware attached

Hardware Configuration

no other hardware attached

Version

v2.0.14

IDE Name

Arduino IDE 1.8.19

Operating System

Ubuntu

Flash frequency

80

PSRAM enabled

yes

Upload speed

921600

Description

When the ESP32 is connected to an AP, it stops receiving unicast ESP-NOW messages. It still receives broadcast messages.

I have manually checked/set the channel of my AP with my setup.

My original code was written toward all ESP8266's and works, but I decided to port the RX side to an ESP32-C3.

Right now I'm transmitting from ESP8266's to an ESP32-C3 and unicast in connected STA mode seems broken.

Sketch

I've placed my stripped down testcase in a repo:

https://github.com/goatzillax/espnow_crosstest

Debug Message

none

Other Steps to Reproduce

My TX side is an ESP8266, and the RX side is an ESP32-C3. The RX side seems broken.

I have checked existing issues, online documentation and the Troubleshooting Guide

me-no-dev commented 9 months ago

ESP-NOW works only on the channel that the radio is currently on. When you have set WiFi to enable STA and you are connected to a network, the radio's channel is equal to that of the AP that you have connected to. So ESP-NOW is working, but because the Radio have changed it's channel, you are probably listening on the wrong one.

goatzillax commented 9 months ago

What wording do I need to use to communicate that I have attempted every check possible to make sure they are on the correct channel even in STA mode?

My full app works on an 8266. The RX side connects as STA, and the TX side scans all wifi channels until it finds the correct one. When the RX is moved over to the ESP32-C3, it never manages to find a working channel.

I only stripped the test case down to make it easier to review.

goatzillax commented 9 months ago

Let me try saying the same thing in a different way.

The TX is set to channel 5 with the unicast address of the receiver. Here is the output of the RX with bogus STA credentials so it falls back to SoftAP mode and I press the reset button on the transmitter.


[  6864][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 5 - STA_DISCONNECTED
[  6864][W][WiFiGeneric.cpp:1061] _eventCallback(): Reason: 201 - NO_AP_FOUND
[  6867][D][WiFiGeneric.cpp:1085] _eventCallback(): WiFi AutoReconnect Running
[  9705][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 5 - STA_DISCONNECTED
[  9705][W][WiFiGeneric.cpp:1061] _eventCallback(): Reason: 201 - NO_AP_FOUND
[  9708][D][WiFiGeneric.cpp:1085] _eventCallback(): WiFi AutoReconnect Running
[ 11921][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 11 - AP_STOP
[ 11922][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 10 - AP_START
192.168.4.1
Wi-Fi Channel: 5
msg received

So that works. 192.168.4.1 is the SoftAP address.

I reflash the RX with correct wifi creds and it connects to my network, and I press the reset button on the transmitter.

MAC Address:  xx:xx:xx:xx:xx:xx

192.168.2.155

Wi-Fi Channel: 5

And that's it. I don't get a message received.

Here is the nmcli dump from the Linux machine.

IN-USE  BSSID              SSID            MODE   CHAN  RATE        SIGNAL  BARS  SECURITY  
        xx:xx:xx:xx:xx:xx  ESP_xxxxxx      Infra  5     135 Mbit/s  100     ▂▄▆█  --        
*       xx:xx:xx:xx:xx:xx  xxxxxx          Infra  5     130 Mbit/s  94      ▂▄▆█  WPA1 WPA2 

The second AP is of course the one I'm connecting to.

To recap:

So does it sound like I don't have the right channel?

me-no-dev commented 9 months ago

Can you try to also have AP enabled, while STA is connected?

goatzillax commented 9 months ago

Yes. I just modified my code to have it run WiFi.disconnect() upon button press.

When it first boots up, it has both AP and STA configured and connected. No messages are ever received from the TX.

MAC Address:  xx:xx:xx:xx:xx:xx

192.168.2.155

192.168.4.1

Wi-Fi Channel: 5

I can ping them from another host after connecting to each one.

$ ping 192.168.2.155
PING 192.168.2.155 (192.168.2.155) 56(84) bytes of data.
64 bytes from 192.168.2.155: icmp_seq=1 ttl=255 time=159 ms
^C
--- 192.168.2.155 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 158.801/158.801/158.801/0.000 ms

$ ping 192.168.4.1
PING 192.168.4.1 (192.168.4.1) 56(84) bytes of data.
64 bytes from 192.168.4.1: icmp_seq=1 ttl=255 time=2.69 ms
64 bytes from 192.168.4.1: icmp_seq=2 ttl=255 time=1.16 ms
^C
--- 192.168.4.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 1.162/1.927/2.693/0.765 ms

Once I press the button, the STA disconnects, the AP stays running, and now it receives messages.

disconnecting WiFi
[ 15831][V][WiFiGeneric.cpp:362] _arduino_event_cb(): STA Disconnected: SSID: xxxxxxxxxx, BSSID: xx:xx:xx:xx:xx:xx, Reason: 8
[ 15831][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 5 - STA_DISCONNECTED
[ 15838][W][WiFiGeneric.cpp:1061] _eventCallback(): Reason: 8 - ASSOC_LEAVE
msg received
msg received
[ 58978][V][WiFiGeneric.cpp:407] _arduino_event_cb(): AP Station Connected: MAC: xx:xx:xx:xx:xx:xx, AID: 1
[ 58979][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 12 - AP_STACONNECTED
[ 59026][V][WiFiGeneric.cpp:421] _arduino_event_cb(): AP Station IP Assigned:192.168.4.2
[ 59027][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 14 - AP_STAIPASSIGNED
goatzillax commented 9 months ago

Looking over the tests/examples:

  1. The tests/examples only strictly test a. Channel 1, which is the default anyways so that doesn't make a lot of sense b. Slave operating as SoftAP
  2. The tests/examples don't even keep up with some of your own API breakages, which kind of hints at them not even being run

And again, this functionality works on the ESP8266 so this appears to be a regression.

The tests should sweep the channels. I believe this can be automated with no additional hardware and minor code tweaks, and it will likely more closely resemble a real use case.

me-no-dev commented 9 months ago

One option would be to post an issue in ESP-IDF's repository and see if they have any idea. Arduino 2.0.14 runs on ESP-IDF 4.4.6. If you install from github, then master is on ESP-IDF v5.1.2.

goatzillax commented 9 months ago

Yes, I found multiple issues on the ESP-IDF repository like this one:

https://github.com/espressif/esp-idf/issues/10341

Which has been open for nearly a year. There was another one but I can't seem to find it again.

Given what I've seen of the testcases, it's likely that the functionality is still quite broken because there's no testing, and the testcase won't even compile due to API breakage.

Xiehanxin commented 8 months ago

@me-no-dev I am not sure the idf version in Arduino IDE 1.8.19, this issue should be fixed in IDF 5.0. @goatzillax if you want to use the IDF 4.3 / 4.4 ,you can inir the espnow first and then connect to an AP.

me-no-dev commented 8 months ago

If fixed in 5.0, then user can try the latest Alpha/RC of ESP32 Arduino v3.0.0

PepeTux commented 5 months ago

Hello all, here there is a working code, it have both transmitter and receiver, running on the ESP32, to set the module as WIFI_STATION and connect to an AP, must be configured as: WiFi.mode(WIFI_AP_STA );

As the ESP-Now IDF said: it must be set as the channel that station or softap is on. image

The transmitter have a search channel routine to find the receiver channel,

Tested on a ESP32-C3 (revision v0.4). Arduino IDE 2.3.2, v2.0.14 (ESP-IDF v4.4.6).

Note: Change: ESP_IF_WIFI_STA by this: WIFI_IF_STA in both code, Transmitter and Receiver.

Enjoy coding !

Jose Luis