espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
12.93k stars 7.09k forks source link

ESP-NOW does not workig with WiFi (STA) mode (IDFGH-8924) #10341

Open rajneeshsinha opened 1 year ago

rajneeshsinha commented 1 year ago

Answers checklist.

General issue report

Hello

I am working on ESP-IDF release version-4.4 and having requirements to put the ESP32 device on APSTA mode mean, device should work in AP mode (start web page) and in STA mode connect to router to get internet access. With these both mode device work correctly but after initializing ESP-NOW it doesn't works (Rx data call back handler never called).

I have tried following things before posting this issue here:

  1. Start AP to launch web page and start STA together to connect with router --> ESP-NOW not working
  2. Start only AP to launch web page and init ESP-NOW (start esp-now) --> ESP-NOW working
  3. Start only STA to connect with router and init ESP-NOW (start esp-now) --> ESP-NOW not working
  4. Start only STA to connect with router and read channel number and set this channel number to init ESP-NOW (start esp-now) --> ESP-NOW not working
  5. Start only STA to connect with router and hard-coded channel number to 1 and set this channel number to init ESP-NOW (start esp-now) --> ESP-NOW not working
  6. From above step-1 to step-5 test, I also tested ESPNOW in both station and softap mode --> ESP-NOW not working

I already checked following links:

Any suggestions will be appreciated.

kriegste commented 1 year ago

Have you tried to disable modem sleep, i.e.

esp_wifi_set_ps(WIFI_PS_NONE);

Xiehanxin commented 1 year ago

hi @rajneeshsinha. have you tried the ESP-NOW example, and could you please provide some error log

rajneeshsinha commented 1 year ago

@kriegste Thanks for suggestion. I have tried with your suggestion to put the MCU in NO POWER SAVING mode but it didn't work.

Attached image for your reference,

image

So, if I comment the WiFi_connect then esp-now works. Following is the wifi_connect function does:

`void wifi_connect(char ssid, char pass) { wifi_config_t wifi_config; bzero(&wifi_config, sizeof(wifi_config_t)); memcpy(wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); memcpy(wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));

wifi_state_p.wifi_state = false;
ESP_ERROR_CHECK( esp_wifi_disconnect() );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
esp_wifi_connect();

}`

Do you have any other suggestion that need to try? Did you try at your side with this same requirement application and it works? Let me know if you need any other details from my end?

I am suspecting, running ESP32 in station mode (to get internet access from router) + ESP-NOW broadcaster/receiver mode is not feasible at the movement till that we have proper solution or any work around works here.

kriegste commented 1 year ago

Did you do this, too?

esp_netif_create_default_wifi_sta();

wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_config);

esp_wifi_start();
ramiws commented 1 year ago

same issue here, once esp_wifi_connect(); is called, esp now does not work

goatzillax commented 7 months ago

Congratudolences, guys! This core functionality has been broken for at least a year!

Xiehanxin commented 6 months ago

hi @goatzillax this issue is fixed in IDF 5.0 and later version. if you want tou use it on 4.3/4.4, you should init esp-now first ,then connect to AP, and the esp-now can send packet normally. and we will backport to 4.4

goatzillax commented 6 months ago

@Xiehanxin I wonder if there is some sort of miscommunication here.

I'm on 2.0.14 of the ESP32 package which apparently is IDF 4.4 (correct me if I'm wrong).

I just tried moving esp_now_init before connecting the RX to an AP, and it still fails. My testcase is otherwise the same. I press the button, it disconnects, and then the ESP-NOW messages start showing up.

So as far as I can tell, moving esp_now_init before WiFi.begin() is not a workaround for IDF 4.4.

I've updated my testcase.

https://github.com/goatzillax/espnow_crosstest

Can you show me the testcase you used to verify functionality?

zhangyanjiaoesp commented 3 months ago

@goatzillax I noticed that your ESPNOW packets are broadcast packets. When STA is connected to wifi, it will only receive the broadcast packet whose bssid is equal to the associated AP bssid. Therefore, packet receiving fails. Suggest you use unicast to send.

goatzillax commented 3 months ago

@goatzillax I noticed that your ESPNOW packets are broadcast packets. When STA is connected to wifi, it will only receive the broadcast packet whose bssid is equal to the associated AP bssid. Therefore, packet receiving fails. Suggest you use unicast to send.

My comment says, "// broadcast works, unicast does not if RX is connected to an AP".

I have the broadcast address as a placeholder in my repo.

I do not believe you understand this bug or my code.

Unicast to an RX connected to a STA, even when all devices are on the same channel, does not work.

The last I checked, Espressif's test cases do not test this specific scenario.

It's claimed to be fixed in 5.0 but given the total situation I highly doubt it.

zhangyanjiaoesp commented 3 months ago

@goatzillax In this https://github.com/goatzillax/espnow_crosstest testcase, I don't see the esp_now_add_peer() in the rx_esp32_c3.ino if you send unicast.

goatzillax commented 3 months ago

@goatzillax In this https://github.com/goatzillax/espnow_crosstest testcase, I don't see the esp_now_add_peer() in the rx_esp32_c3.ino if you send unicast.

I am almost certain that requirement was removed in the ESP32 version of the libraries. I tried to make that painfully clear in the file naming -- the receiver is an ESP32-C3 and the transmitter is an ESP8266, and their libraries are not the same although they should be able to communicate with each other over ESP-NOW.

https://github.com/espressif/arduino-esp32/issues/8912

Again, I don't think you understand the bug, testcase, and now the API.

The testcase boots up with the RX in STA mode. No messages are received. When I press the button, it disconnects from STA and goes into SoftAP mode, and messages are then received. All without having called esp_now_add_peer.

This is why I suspect espressif's own testcase aren't being run. I don't think they'll even compile due to API changes.

goatzillax commented 3 months ago

Just checked the docs, it does not indicate that esp_now_add_peer is required to receive messages. In fact I don't think that was ever a requirement as I'm looking back at some old code. It was the master/slave notion they did away with.

zhangyanjiaoesp commented 3 months ago

Just checked the docs, it does not indicate that esp_now_add_peer is required to receive messages. In fact I don't think that was ever a requirement as I'm looking back at some old code. It was the master/slave notion they did away with.

Sorry, I made a mistake, it's not required to add peer when receiving.

zhangyanjiaoesp commented 3 months ago

https://github.com/espressif/arduino-esp32/issues/8912

I will test the case on Arduino. By the way, can you please have a try on Arduino 3.0.0 (which is based on IDF v5.1)?

PepeTux commented 3 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

zhangyanjiaoesp commented 1 month ago

@rajneeshsinha @goatzillax do you still have this problem?

goatzillax commented 1 month ago

I tried the esp_wifi_set_promiscuous workaround that PepeTux mentioned, but that did not work for me.

I don't know what you mean by Arduino 3.0.0. Do you mean the arduino-esp32 3.0.0 board package? I tried that version, and it is still broken in the exact same way.

I have not seen a test case in any suite that indicates anybody actually understands the bug in the first place.

No test case == not fixed

leonardodanelutti commented 1 month ago

I have the same issue, once esp_wifi_connect() is called, esp now stops to work.

zhangyanjiaoesp commented 3 weeks ago

I don't know what you mean by Arduino 3.0.0. Do you mean the arduino-esp32 3.0.0 board package? I tried that version, and it is still broken in the exact same way.

Yes, I mean the arduino-esp32 3.0.0 board package.

zhangyanjiaoesp commented 3 weeks ago

I have the same issue, once esp_wifi_connect() is called, esp now stops to work.

@leonardodanelutti can you provide a demo to test?

leonardodanelutti commented 3 weeks ago

Sorry @zhangyanjiaoesp, I am using Rust in my project, but I am doing the same things as @rajneeshsinha and @goatzillax on IDF 5.1:

At this point, ESP-NOW stops working if the AP's channel is not 1.

The problem seems to be that ESP-NOW and the Wi-Fi must be on the same channel, but it is impossible to set a channel other than 1 on the ESP-NOW transmitter (error: peer channel is not equal to home channel, send fail!).

goatzillax commented 3 weeks ago

I thought @Xiehanxin confirmed this fixed in IDF 5.1 in Dec 2023. I asked for the testcase back then because it's hard to imagine how a fix can be confirmed without a testcase.

I also provided my own testcase. It's literally sitting in its own repo. The TX side is coded for ESP8266 but you can obviously change that to work on an ESP32 if necessary. You just need two devices. Seems like this should be part of an automated suite.

Now, if you guys have your own testcase for this, great, I wouldn't mind reviewing it.

Again, kind of hard to say this is fixed without a testcase.

zhangyanjiaoesp commented 3 weeks ago

@leonardodanelutti When the STA connects to AP, it will change it's home channel same to the AP. For example, the default channel for STA is channel 1, when STA connects to a channel 5 AP, the STA will change the home channel to 5. So if the home channel of your STA and AP is different, you need to call esp_wifi_set_channel() to set channel of the STA same to AP, at the same time, the channel of the peers should also be consistent.

zhangyanjiaoesp commented 3 weeks ago

@goatzillax I have tested your code on Arduino 3.0.0, and I didn't reproduce your issue. And on Arduino 2.0.14, I can reproduce the issue, so I create a PR https://github.com/espressif/esp32-arduino-lib-builder/pull/165 to fix it, but the config can't be changed, so suggest to use Arduino 3.0.0.

goatzillax commented 3 weeks ago

@goatzillax I have tested your code on Arduino 3.0.0, and I didn't reproduce your issue.

That's interesting. The TX side just sends a message whenever reset is pressed so it's pretty simple.

So when you ran the RX code, you connected it to a STA, then while still connected to the STA (confirmed with a ping from another machine), you pressed reset on the TX device and saw it blink the LED and/or watched the serial port output and it confirmed "msg received"?

leonardodanelutti commented 3 weeks ago

@zhangyanjiaoesp I know that, but as I said for me it is impossible to change the channel of the peer in the ESP-NOW transmitting device. As soon as I call esp_now_send this error is raised: "peer channel is not equal to home channel, send fail!".

zhangyanjiaoesp commented 3 weeks ago

@leonardodanelutti The peer channel in log peer channel is not equal to home channel, send fail! means the peer->channel when you call esp_now_add_peer(peer), you can call esp_now_mod_peer(peer) to change the peer->channel if you have added it.

zhangyanjiaoesp commented 3 weeks ago

@goatzillax I have tested your code on Arduino 3.0.0, and I didn't reproduce your issue.

That's interesting. The TX side just sends a message whenever reset is pressed so it's pretty simple.

So when you ran the RX code, you connected it to a STA, then while still connected to the STA (confirmed with a ping from another machine), you pressed reset on the TX device and saw it blink the LED and/or watched the serial port output and it confirmed "msg received"?

yes

leonardodanelutti commented 3 weeks ago

@zhangyanjiaoesp the error message is displayed when I call esp_now_send not when I add the peer, even if I set the same channel in the STA config

leonardodanelutti commented 3 weeks ago

@zhangyanjiaoesp seem that this should be fixed on 5.2, I will test that

zhangyanjiaoesp commented 3 weeks ago

@zhangyanjiaoesp the error message is displayed when I call esp_now_send not when I add the peer, even if I set the same channel in the STA config

@leonardodanelutti I know the log displayed when call esp_now_send(), when you want to send data to peer, it will check the channel first. Your issue seems to be caused by inconsistent channels, you only need to set the STA channel, AP channel , peer channel to be consistent can solve the problem.

goatzillax commented 3 weeks ago

@goatzillax I have tested your code on Arduino 3.0.0, and I didn't reproduce your issue.

That's interesting. The TX side just sends a message whenever reset is pressed so it's pretty simple. So when you ran the RX code, you connected it to a STA, then while still connected to the STA (confirmed with a ping from another machine), you pressed reset on the TX device and saw it blink the LED and/or watched the serial port output and it confirmed "msg received"?

yes

Huh. One last thing -- did you change the TX to transmit to a specific MAC (I.e. make it use unicast)? I only put the broadcast in as a placeholder.

zhangyanjiaoesp commented 3 weeks ago

@goatzillax I have tested your code on Arduino 3.0.0, and I didn't reproduce your issue.

That's interesting. The TX side just sends a message whenever reset is pressed so it's pretty simple. So when you ran the RX code, you connected it to a STA, then while still connected to the STA (confirmed with a ping from another machine), you pressed reset on the TX device and saw it blink the LED and/or watched the serial port output and it confirmed "msg received"?

yes

Huh. One last thing -- did you change the TX to transmit to a specific MAC (I.e. make it use unicast)? I only put the broadcast in as a placeholder.

yes, I have changed it to my communicate device MAC

goatzillax commented 3 weeks ago

OK. Well, all I can do is leave this here.

I updated my testcase to make it slightly harder to mess up; all you have to do is set your SSID/password and channel in the RX code.

I literally made a video of what I'm seeing:

https://www.youtube.com/watch?v=dEBRfFWL9lQ

When the code starts up, it connects to an AP and no ESP-NOW messages are received.

I press the button, it disconnects, and it starts receiving messages.

The serial console text from the video:

ESP-IDF major 5
ESP-IDF minor 1
MAC Address:  B4:E6:2D:E9:FE:6E
192.168.2.166
Wi-Fi Channel: 3
Initializing ESP-NOW
disconnecting WiFi
msg received
msg received

Can you point out where in your test suite this exact functionality is actually tested?