Hieromon / AutoConnect

An Arduino library for ESP8266/ESP32 WLAN configuration at runtime with the Web interface
https://hieromon.github.io/AutoConnect/
MIT License
911 stars 190 forks source link

ESP32 problem #593

Closed Evgen2 closed 1 year ago

Evgen2 commented 1 year ago

AutoConnect on ESP32 runs in a wrong way. I take example HelloWorld\HelloWorld.ino on Platformio with platformio.ini [env:esp32dev] platform = espressif32 board = esp32dev framework = arduino lib_deps = hieromon/AutoConnect@^1.4.2 monitor_speed = 115200 As well I uncomment #define AC_DEBUG in \src\AutoConnectDefs.h This behavior can be better seen in a short video on YouTube. Sometimes all runs well and it is possible to fill SSID and password for WiFi, sometimes apply not work, but mostly problem with entering in "Configure New AP" and "Open SSIDs" menu item

Check this behavior with Autoconnect 1.3 version - A behavior is the same. espressif32 platform version tested 6.0 and latest 6.1

Hieromon commented 1 year ago

@Evgen2 I cannot reproduce the issue. I have repeated with every release of AutoConnect that I test all the examples with real modules to make sure they work. Of course, Hello World has been confirmed to work properly on ESP32-C3-DevkitM-1, NodeMCU-32S, ES32-S2-WROVER, ESP32-WROVER-E, ESP32-WROOM-32D, ESP32-CAM etc.

The video does not diagnose the detailed operation inside AutoConnect. Please refer to the documentation to collect AC_DEBUG traces. In some cases, you may also need the PB_DEBUG log.

Evgen2 commented 1 year ago

I was sure everything was working, but deal mainly with esp8266 and now find this on esp-wroom-32

Processing esp32dev (platform: espressif32; board: esp32dev; framework: arduino)


PLATFORM: Espressif 32 (5.2.0) > Espressif ESP32 Dev Module
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
 - framework-arduinoespressif32 @ 3.20005.220925 (2.0.5)
 - tool-esptoolpy @ 1.40201.0 (4.2.1)
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch3

``` - 

Now I add PB_DEBUG  and add as well millis() out. Here are two logs - "good"  from reset to show /_ac/config   webpage
and "wronng" from reset to break connect at entering  /_ac/config   webpage

[Good.txt](https://github.com/Hieromon/AutoConnect/files/11181163/Good.txt)
[Wrong.txt](https://github.com/Hieromon/AutoConnect/files/11181164/Wrong.txt)
Hieromon commented 1 year ago

I'm seeing strange phenomena that I have never seen before.

53858 $$$$$ return _token_LIST_SSIDSSID_COUNT HIDDEN_COUNT blk:1270 CONFIG_IP blk:1270 blk:18

The log at $$$$$ prefix is neither AutoConnect nor PageBuilder. However, the string that follows it is clearly from PageBuilder. It appears that the sketch was not built correctly and the constant string area is conflicting.

It seems that the version of platform-espressif32 is out of date (it refers to ESP32 Arduino Core 2.0.5), replace it with the latest Release 6.1.0 and try again. In addition to that, increase the size of the app partition.

platformio.ini

board_build.partitions = min_spiffs.csv
Evgen2 commented 1 year ago

I have made many attempts to identify the problem, change platform versions, add a lot of additional debug message and now find that this stange phenomena associated with the function WiFi.scanNetworks() Web server kicks client just at execution of WiFi.scanNetworks()

Google finds me similar problem with scanNetworks and Arduino framework https://github.com/espressif/arduino-esp32/issues/4554

And seems that I find solution - just call WiFi.scanNetworks(false, true , true); instead of WiFi.scanNetworks(false, true);

third parameter - bool passive what does that mean i have no idea, but it seems work. if it is not working for some time case of "unstable work"

int16_t WiFiScanClass::scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300U, uint8_t channel = (uint8_t)0U, const char *ssid = (const char *)nullptr, const uint8_t *bssid = (const uint8_t *)nullptr)

Hieromon commented 1 year ago

Uh, you may have stepped on a mine. It's a hard nut to crack. I am aware that I do not have sufficient knowledge to solve this problem. The issue you indicate may be related to the WiFi channel and the country you are using. And in my country it is difficult to replicate this problem and I have not found a perfect solution.

However, to help us in future investigations, I am including below my knowledge that may be useful.

WiFi channels

In general radio communication, the frequency band used is divided into several parts to prevent interference between transmitters and receivers using the same frequency band (i.e. the baseband). These are called channels. Although it is possible to communicate using different proximity channels for the transmitter and receiver, the noise will be introduced and the communication speed will be reduced. Also, in the IEEE802.11b as 2.4GHz WiFi standard, at a distance of more than 5 channels, the signal strength will be too low and the connection will be cut off.

WiFi_Bandwidth

The ESP32 has one 2.4GHz receiver and one 2.4GHz transmitter, but each cannot transmit and receive on different channels simultaneously. They are always the same. That is, the channel on which packets are sent out and the channel on which they are accepted are the same.

And the channel range to be scanned depends on the country used. This means that your android device and the access point firmware must be correctly configured for the same country code. For some devices, such as those of unknown origin, this country code may be ambiguous.

The ESP32 WiFi driver has an API to set the country code; AutoConnect does not explicitly set the country code, so WIFI_COUNTRY_POLICY_AUTO is used. However, this setting is actually tricky. The following is a quote from the ESP-IDF Programming Guide.

If the connected AP has country IE in its beacon, the country info equals to the country info in beacon

This means, if your Android device and the access point have different country codes embedded, the redirection will probably fail after AutoConnect is established. Because the ESP32's STA WiFi channel may force to change by a new AP country code channel range.

WiFi Scanning methods

WiFi_Scan

The problem with ESP32's active scan is that the transmitter's channels change one after another. This means losing connection with already connected AP during the scan. The following is taken from the ESP32 datasheet.

Note that when ESP32 is in Station mode, performing a scan, the SoftAP channel will be changed.

On the other hand, the drawback of passive scanning is that it cannot find APs with hidden SSIDs. The hidden SSID does not transmit its own beacon for detection.

ESP32 WiFi scanning strategy

To avoid disconnections from the AP due to WiFi scanning, the ESP-IDF WiFi driver adopts two different strategies. The following is a quote from the ESP-IDF Programming Guide - WiFi Driver.

Whether it is a foreground scan or background scan depends on the Wi-Fi driver and cannot be configured by the application.

What a mess! They say that the WiFi driver arbitrarily decides depending on whether the ESP32 has a station connection. So what is the difference between the two?

The biggest difference is whether the device (i.e. your Android device)connecting to the ESP32 SoftAP is using the trick of returning to the home channel each time the scan channel moves to avoid being disconnected by the AP channel changes that accompany the scan.

the difference in the all-channel background scan is that the Wi-Fi driver will scan the back-to-home channel for 30 ms before it switches to the next channel to give the Wi-Fi connection a chance to transmit/receive data.

back-to-home channel?, Again, an unidentified concept has emerged. The ESP-IDF documentation makes frequent appearances of these dubious concepts. WiFi Home Channel is follows:

In AP mode, the home channel is defined as the AP channel. In Station mode, home channel is defined as the channel of AP which the station is connected to. In Station/AP-coexistence mode, the home channel of AP and station must be the same

This means that a keep-alive beacon must be transmitted to the Android WiFi client device during the 30ms period of switching scan channels. Moreover, the Android WiFi client device must patiently wait for the beacon to be continued. Will it work that well?

Under weak WiFi radio signal conditions, the ESP32 SoftAP will generally disconnect from the client. This phenomenon also occurs on my iPhone. It loses connection at about -70dB RSSI.

Whether you use the Open SSIDs menu or the Configure new AP menu, either a foreground scan or a background scan will be used, depending on whether ESP32 already has a connection to the AP at the time you perform it. It is not an intentional choice by the application. Whichever scanning strategy is used, as long as you perform an active scan, your client device may lose the channel needed to connect to SoftAP.

You mentioned that the redirects were stable when you were passive scanning. The reason for this is probably because of the above phenomenon.

However, passive scanning cannot find hidden SSIDs; The Open SSIDs menu performs a WiFi scan to detect SSIDs stored in AutoConnectCredential. Also, the AutoConnectConfig::autoReconnect setting also enables automatic reconnection to the hidden SSIDs discovered by the active scan. That's because it uses the BSSIDs it finds using active scanning as clues to connect.

Even if the SSID is hidden, once it has been manually configured using Config New AP, it should be possible to discover and auto-reconnect to that AP. It is literally an AutoConnct connection. If you are willing to throw away this feature, then passive scanning would be available as well.

Evgen2 commented 1 year ago

However, passive scanning cannot find hidden SSIDs; Configure new AP shows me "Total:3 Hidden: 1", and more stgange Open SSIDs shows only one AutoConnect_1 AutoConnect_2 I'll try to find time to take a better look.

Hieromon commented 1 year ago

@Evgen2 I dont know why. The WiFi Driver documentation in the ESP-IDF Programming Guide does indeed describe it. Did you confirm that with my comment mentioning it?

The WiFi.scanNetworks implementation of the ESP32 Arduino core passes WIFI_SCAN_TYPE_PASSIVE;. I cannot confirm anything deeper than that.

https://github.com/espressif/arduino-esp32/blob/224e778b8ed7728a2b104c98c232f34fa34a357c/libraries/WiFi/src/WiFiScan.cpp#L76

Evgen2 commented 1 year ago

It's some sort of black magic. I tested a number of versions of platform = espressif32 in [env:esp32dev] platform = espressif32@version and have find that with 3.0 all work well, but with newer versions even pure WiFi.begin(MySSID, MyPWD); can't connect. And finally with the help of the guys from the channel https://t.me/ProEsp8266 I have find that my WiFi router work with pure WPA. After switching to WPA2 everything is back to normal connecting and scaning