Hallo, ich hab hier einen ESP32 (ESP32 Thing von Sparkfun), den ich mit PlatformIO/Arduino Framework programmiere. Beim Start soll sich der ESP32 mit meinem WLAN (Fritzbox/1750E Repeater Mesh) verbinden, und eine E-Mail versenden (danach geht er in den Deep Sleep, bis er wieder von Extern resetted wird). Das funktioniert leider nur in 70% der Fälle. Ziemlich häufig bleibt der Controller beim Verbindungsaufbau hängen (es wird nicht mal ein Watchdog ausgelöst!). Oder er crasht dabei, und resetted sich. Letzteres ist nicht wirklich schlimm, da es danach im zweiten Anlauf meist klappt. Aber wenn sich der Controller komplett aufhängt, ist das natürlich fatal. Das bekommt man von außen nicht mit und der Akku entleer sich rasend schnell (da der ESP nicht mehr in den DeepSleep kommt). Nun meine Fragen dazu: Ist das beim ESP32 "normal", dass die WLAN Verbindung so unzuverlässig ist? Liegt es am Arduinio Framework (ist das IDF hier stabiler)? Könnte es auch an der Fritzbox/dem Mesh liegen? PS: Den Code habe ich gerade nicht griffbereit, ist aber nichts Besonderes (WiFi.begin()). Kann ich aber gerne nachliefern.
Ist denn die Spannungsversorgung stabil? Spendiere mal einen 100uF Elko, der scheint dem Board zu fehlen. Welchen Akku benutzt Du? Wir brauchen mehr Infos über die Schaltung und das Programm.
Außerdem wäre es interessant, ob du die onboard Antenne oder eine aufgesteckte benutzt. Die letzten ESP32 Boards waren bei mir immer so verdrahtet (Widerstand) dass eine externe Antenne angeschlossen werden musste. Da hatte ich eine Weile auch mit WLAN gekämpft bis ich das bemerkte.
Hallo, ich habe nur einen ESP32 mit Akkubetrieb hier laufen. Feste IP, da ich nicht auf den DHCP warten willl, kostet nur Zeit. Mit DHCP unbedingt den Event abfragen, ob er eine aktuelle IP bekommen hat, Connect pausschal sagt nur, daß er mit dem AP verbunden ist. Normalerweise ist er bei mir in ca. 1-2s mit AP und MQTT Broker verbunden. Manchmal dauert es aber auch bis zu 5s, keine Ahnung warum. Ich habe inen Timeout um die Verbindunsabfrage, wenn er nach 6s nicht sauber verbunden ist, geht er eben wieder schlafen. Stört hier auch nicht, ist nur ein Temp./Feuchte/Luftdruck-Sensor, der alle 5 Minuten die Daten schickt. Spannungsversorgung ist eine LiFePO4 18650 Zelle mit 1500mAh, lebt 2 Monate bis zum neu laden. Modul ein nackter ESP32 Wroom, 220uF am Modul über der Betriebsspannung. Gruß aus Berlin Michael
Hier ist der Code:
1 | #include <Arduino.h> |
2 | #include "Mailing.h" |
3 | |
4 | #define WIFI_SSID "MySSID" |
5 | #define WIFI_PASSWORD "MyPWD" |
6 | |
7 | |
8 | RTC_DATA_ATTR int gPersistentBootCount = 0; // Persistent even during deep sleep!!! |
9 | uint8_t gWifiConnectTryCounter = 0; |
10 | |
11 | |
12 | void SendMsg() |
13 | { |
14 | Serial.println("Turning on radio"); |
15 | WiFi.mode(WIFI_STA); |
16 | |
17 | Serial.println("Trying to establishing connection to WiFi"); |
18 | WiFi.persistent(false); |
19 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); |
20 | |
21 | while ((WiFi.status() != WL_CONNECTED) && (gWifiConnectTryCounter < 10)) |
22 | { |
23 | delay(1000); |
24 | gWifiConnectTryCounter++; |
25 | Serial.print("."); |
26 | } |
27 | |
28 | if (WiFi.status() == WL_CONNECTED) |
29 | { |
30 | Serial.println("Connected successfully to wifi."); |
31 | setupMailer(); |
32 | sendMail(); |
33 | } |
34 | else |
35 | { |
36 | Serial.println("Counld NOT establish Connection to WiFi Network."); |
37 | } |
38 | |
39 | Serial.println("Disconnecting wifi"); |
40 | WiFi.disconnect(); |
41 | |
42 | Serial.println("Turning off Radio"); |
43 | WiFi.mode(WIFI_OFF); |
44 | } |
45 | |
46 | void setup() |
47 | { |
48 | Serial.begin(115200); |
49 | |
50 | ++gPersistentBootCount; |
51 | Serial.println("Boot number: " + String(gPersistentBootCount)); |
52 | |
53 | if (gPersistentBootCount == 1) |
54 | { |
55 | Serial.println("Sending mail..."); |
56 | SendMsg(); |
57 | |
58 | Serial.println("Going to sleep now."); |
59 | esp_sleep_enable_ext0_wakeup(GPIO_NUM_36, 1); |
60 | esp_deep_sleep_start(); |
61 | } |
62 | else |
63 | { |
64 | Serial.println("Rebooting..."); |
65 | |
66 | // Restart the controller. Will send an E-Mail on next boot |
67 | ESP.restart(); |
68 | } |
69 | } |
70 | |
71 | void loop() |
72 | { |
73 | // Loop is not required. All logic is handled in setup() |
74 | } |
Versorgt wird der Controller über USB, die Antenne ist direkt auf dem Board.
Das delay(1000) funktioniert nicht gut mit des ESPs, damit blockierst Du den ESP, das hat er nicht so gerne. Nimm das mal raus.
Pete K. schrieb: > Das delay(1000) funktioniert nicht gut mit des ESPs, damit blockierst Du > den ESP, das hat er nicht so gerne. Nimm das mal raus. Bist du da sicher? Der WIFi Stack läuft beim ESP32 ja auf Core 0, der User Code auf Core 1. Damit sollte sich da nichts blockieren. Oder bin ich da falsch informiert?
Jens schrieb: > Ist das beim ESP32 "normal", dass die WLAN Verbindung so unzuverlässig > ist? > Liegt es am Arduinio Framework (ist das IDF hier stabiler)? > Könnte es auch an der Fritzbox/dem Mesh liegen? Ohne ins Detail zu gehen, alle genannten Quellen sind nicht richtig stabil! Z.B. der Fritz Repeater hat ein FW Problem, WLAN stirbt regelmäßig bei mir bzw. friert ein auf Schneckentempo, nach Reset läuft alles wieder. Es gibt auch einige Hinweise im Netz, wie man mit den ESP32 Fehlversuchen umgehen muss, aber auch viel Unsinn dazu. Das Framework hat nicht die Reife, wie das von ESP8266, wird aber jedes Jahr stabiler! Ich kann MicroPython auf dem ESP32 empfehlen, das macht viel Freude!
Jens schrieb: > Der WIFi Stack läuft beim ESP32 ja auf Core 0, der > User Code auf Core 1. Damit sollte sich da nichts blockieren. Oder bin > ich da falsch informiert? Das wäre mir neu. Ich habe selber die ganzen WLAN/Server Routinen bei mir auf den 2. Core gelegt. Unter Arduino läuft ALLES auf den 1. Core.
Pete K. schrieb: > Das delay(1000) funktioniert nicht gut mit des ESPs, damit > blockierst Du > den ESP, das hat er nicht so gerne. Nimm das mal raus. Nein, das delay blockiert nicht. Es ruft wiederholt yield() auf, was der Firmware des ESP Zeit abgibt.
John P. schrieb: > Unter Arduino läuft ALLES auf den 1. Core. Das stimmt so nicht. Der Radio Stack läuft definitiv auf Core 0, der User Code auf Core 1. "CPU 0 is also called Protocol CPU (PRO_CPU) and CPU 1 Application CPU (APP_CPU). The CPU 0 controls the WLAN, Bluetooth and other internal peripherals such as SPI, I2C, ADC, etc., while the CPU 1 is available to our user program. Skits that we write in the main loop and upload to the ESP are always executed on the CPU 1 without exception."
Falls es noch interessiert: ab ESP-IDF V3.3 dürften die Verbindungsprobleme behoben sein. Der Umstieg dürfte nicht allzu viele Änderungen an der Software erfordern.
John P. schrieb: > Unter Arduino läuft ALLES auf den 1. Core. Wenn man die Version mit 2 Kernen vorliegen hat. Es gibt die ESP32 auch mit einem Kern.
Stefan ⛄ F. schrieb: > Nein, das delay blockiert nicht. Es ruft wiederholt yield() auf, was der > Firmware des ESP Zeit abgibt. Schreib bitte keinen Unsinn, delay ruft vTaskDelay von FreeRTOS auf. Einfach mal in den Quellcode schauen.
1 | void delay(uint32_t ms) |
2 | {
|
3 | vTaskDelay(ms / portTICK_PERIOD_MS); |
4 | }
|
John Doe schrieb: > Schreib bitte keinen Unsinn, Tu ich nicht. Ich zitiere aus der Datei core_esp8266_wiring.c vom Ardino ESP8266 Core in Version 2.3.0. Das ist die Version, mit der ich arbeite:
1 | void delay(unsigned long ms) { |
2 | if(ms) { |
3 | os_timer_setfn(&delay_timer, (os_timer_func_t*) &delay_end, 0); |
4 | os_timer_arm(&delay_timer, ms, ONCE); |
5 | } else { |
6 | esp_schedule(); |
7 | }
|
8 | esp_yield(); <---------- Da ist das yield |
9 | if(ms) { |
10 | os_timer_disarm(&delay_timer); |
11 | }
|
12 | }
|
Ok, das Wort "wiederholt" war hier falsch. Trotzdem wird die Zeit an das Betriebssystem abgegeben, so dass der Kern meiner Aussage richtig war. Das ist übrigens Arduino Standard, siehe die Datei wiring.c aus dem AVR core:
1 | void delay(unsigned long ms) |
2 | {
|
3 | uint32_t start = micros(); |
4 | |
5 | while (ms > 0) { |
6 | yield(); <---------- Da ist das yield |
7 | while ( ms > 0 && (micros() - start) >= 1000) { |
8 | ms--; |
9 | start += 1000; |
10 | }
|
11 | }
|
12 | }
|
Stefan ⛄ F. schrieb: > John Doe schrieb: >> Schreib bitte keinen Unsinn, > > Tu ich nicht. Ich zitiere aus der Datei core_esp8266_wiring.c vom Ardino > ESP8266 Core in Version 2.3.0. Das ist die Version, mit der ich arbeite: Was an "ESP32" hast Du nicht verstanden?
John Doe schrieb: > Was an "ESP32" hast Du nicht verstanden? Ja, das ist wohl der Knackpunkt. Ich bin im falschen Film. Allerdings dient vTaskDelay() ebenfalls dazu, dem Betriebssystem zeit abzugeben. Meine Aussage "das delay blockiert nicht" ist daher immer noch richtig. Muss auch so sein, weil diese Bilbiothek sonst nicht dem Arduino Standard entsprechen würde.
Stefan ⛄ F. schrieb: > John Doe schrieb: >> Was an "ESP32" hast Du nicht verstanden? > > Ja, das ist wohl der Knackpunkt. Ich bin im falschen Film. Nix für ungut, Stefan, aber lies doch einfach in Zukunft die Posts gründlich durch. Ist ja fast schon die Regel, dass Du drauflos schreibst, bevor Du richtig gelesen hast. Möchtest Du Beispiele aus dem Forum hier haben? > Allerdings dient vTaskDelay() ebenfalls dazu, dem Betriebssystem zeit > abzugeben. Meine Aussage "das delay blockiert nicht" ist daher immer > noch richtig. Ändert aber nichts daran, dass yield() überhaupt nix mit dem ESP32 zu tun hat.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.