Forum: Mikrocontroller und Digitale Elektronik WiFi Connect frisst RAM ESP8266


von Stefan M. (peff)


Lesenswert?

Hi,

habe da ein Problem was alle paar Tage auftritt und regelmäßig zu Reboot 
der Devices wegen Speichermangel führt.
Ich nutze die 8266 in Bereichen wo nicht immer WLAN vorhanden ist teils 
Zeitlich gesteuert / teils manuell , daher deaktiviere ich es sobald die 
Verbindung abbricht und Versuche in regelmäßigen Abständen einen 
Reconnect.
Hiermit:
1
void Connect() {
2
  //  WiFi.mode(WIFI_OFF);
3
  Serial.setDebugOutput(true);
4
  WiFi.persistent(false);  // https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/generic-class.html#mode
5
  Serial.println(F("WiFi.persistent(false) - Done"));
6
  Serial.print(F("Remaining free RAM: "));
7
  Serial.println(formatBytes(ESP.getFreeHeap()));
8
  WiFi.setAutoReconnect(false);
9
  Serial.println(F("WiFi.setAutoReconnect(false) - Done"));
10
  Serial.print(F("Remaining free RAM: "));
11
  Serial.println(formatBytes(ESP.getFreeHeap()));
12
  WiFi.mode(WIFI_STA);
13
  Serial.println(F("WiFi.mode(WIFI_STA) - Done"));
14
  Serial.print(F("Remaining free RAM: "));
15
  Serial.println(formatBytes(ESP.getFreeHeap()));
16
  WiFi.hostname(HOSTNAME);
17
  Serial.println(F("WiFi.hostname(HOSTNAME) - Done"));
18
  Serial.print(F("Remaining free RAM: "));
19
  Serial.println(formatBytes(ESP.getFreeHeap()));
20
  WiFi.begin("xxx", "xxx");
21
  Serial.println(F("WiFi.begin(xxx, xxx) - Done"));
22
  Serial.print(F("Remaining free RAM: "));
23
  Serial.println(formatBytes(ESP.getFreeHeap()));
24
  WiFiOff = false;
25
}


Ob WiFi verbunden ist oder nicht checke ich über die Events:
1
void onWifiConnect(const WiFiEventStationModeGotIP& event) {
2
#ifdef DEBUGSerial
3
  Serial.println(F("Connected to Wi-Fi."));
4
#endif
5
  WiFiconnected = true;
6
  TelnetPrint.begin();
7
  WiFiconnecting_count = 0;
8
  WiFiOff_count = 0;
9
10
}
11
12
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
13
  WiFiconnected = false;
14
  TelnetPrint.stop();
15
#ifdef DEBUGSerial
16
  Serial.println(F("Disconnected from Wi-Fi."));
17
#endif
18
}

Funktioniert auch teils über Tage/Wochen... manchmal aber auch nur einen 
Tag
Denn irgendwann fängt nach einem "Connect" der Speicher an zu 
verschwinden bis es irgendwann knallt.
Habe jetzt schon den Debug Modus WiFi aktiviert, steht aber auch nix 
interessantes drin.

Hier mal der Log dazu:
1
05:13:03.498  WiFiconnected: 0
2
05:13:03.498  (IP unset)
3
05:13:03.498  WiFi-OFF: 1
4
05:13:03.498  WiFi-OFF_count: 1
5
05:13:03.498  WiFi-Connecting_count: 0
6
05:13:03.498  Measurement_count: 15
7
05:13:03.498  Unix-Time: 1658891575
8
05:13:03.498  Records in cache: 372
9
05:13:03.498  
10
05:13:03.498  Remaining free RAM: 25.48 KB
11
05:13:03.498  Lowest free RAM: 25.20 KB
12
05:13:03.498  RSSI: --> 31
13
05:13:03.505  Heap Fragmentation: --> 3
14
05:13:03.505  Heap LargestBlock: --> 24.84 KB
15
05:13:03.505  Try to reconnect
16
05:13:03.511  WiFi.persistent(false) - Done
17
05:13:03.511  Remaining free RAM: 25.48 KB
18
05:13:03.527  WiFi.setAutoReconnect(false) - Done
19
05:13:03.527  Remaining free RAM: 25.48 KB
20
05:13:03.527  mode : sta(44:17:93:0d:59:ce)
21
add if0
22
WiFi.mode(WIFI_STA) - Done
23
05:13:03.527  Remaining free RAM: 25.24 KB
24
05:13:03.534  WiFi.hostname(ESP8266-Keller): lwIP error -16 on interface st (index 0) WiFi.hostname(HOSTNAME) - Done
25
05:13:03.540  Remaining free RAM: 25.24 KB
26
05:13:03.540  WiFi.begin(xxx, xxx) - Done
27
05:13:03.540  Remaining free RAM: 25.02 KB
28
05:13:03.547  ___________________________
29
05:13:03.547  Time taken by Heartbeat: 54 milliseconds
30
05:13:04.502  wifi evt: 8 WiFiconnected: 0
31
05:13:04.502  (IP unset)
32
05:13:04.502  WiFi-OFF: 0
33
05:13:04.502  WiFi-OFF_count: 0
34
05:13:04.502  WiFi-Connecting_count: 19
35
05:13:04.502  Measurement_count: 14
36
05:13:04.502  Unix-Time: 1658891576
37
05:13:04.502  Records in cache: 372
38
05:13:04.502  
39
05:13:04.502  Remaining free RAM: 23.72 KB
40
05:13:04.502  Lowest free RAM: 23.72 KB
41
05:13:04.502  RSSI: --> 31
42
05:13:04.502  Heap Fragmentation: --> 2
43
05:13:04.508  Heap LargestBlock: --> 23.34 KB
44
05:13:04.508  ___________________________
45
05:13:04.515  Time taken by Heartbeat: 16 milliseconds

Man sieht im Durchlauf 05:13:03, dass der "WiFi-OFF_count:" auf 1 
runtergezählt hat und in diesem Heartbeat Loop auf "0" zählt und somit 
"Void Connect" aufgerufen wird.

Die einzelnen Bestandteile des "Void Connect" habe ich auf RAMverlust 
gecheckt, die sind es nicht.
Die Loop wird mit 25.02 KB verlassen.
In der nächsten Heartbeat Loop 05:13:04  sind es dann plötzlich nur noch 
23.72 KB.

Wo ist der Heap geblieben zwischen den beiden Heartbeat Loops?!?
Sobald dieses einmal aufgetreten ist, passiert es jedesmal wenn "Void 
Connect" aufgerufen ist... bis der RAM alle is und es knallt.


Ansonsten ist in der Loop nicht viel drin:
1
  long int t1 = millis();
2
3
  time_t now;
4
  time(&now);
5
6
  if (WiFiconnected == true) {
7
    server.handleClient();                        // Listen for HTTP requests from clients
8
    yield();                                      //allow the cpu to switch to other tasks
9
    ArduinoOTA.handle();                          // IDE OTA Upload via ArduinoIDE
10
  }
11
12
13
  if (ESP.getFreeHeap() < MinFreeHeap) {
14
    MinFreeHeap = ESP.getFreeHeap();
15
  }
16
17
  if (ESP.getHeapFragmentation() > MaxHeapFragmentation) {
18
    MaxHeapFragmentation = ESP.getHeapFragmentation();
19
  }
20
21
  unsigned long currentMillis = millis();


Irgendwelche Ideen?
Was mir auffällt es passiert eher in Umgebungen mit schlechterem WiFi

ESP8266 2.7.4
IDE 1.8.15

Danke für jeden Tip!

von Stefan F. (Gast)


Lesenswert?

Stefan M. schrieb:
> daher deaktiviere ich es sobald die Verbindung abbricht und Versuche
> in regelmäßigen Abständen einen Reconnect.

Das ist gar nicht notwendig, der ESP verbindet sich von ganz alleine 
wieder neu, sobald der AP wieder erreichbar ist. Ich hatte das mehr als 
2 Jahre im Dauertest mit einer Zeitschaltuhr am Router.

Eventuell hängt dein Problem mit den Events zusammen, die habe ich nicht 
genutzt. Mein Quelltext: http://stefanfrings.de/esp8266/WifiMonitor.zip

von Stefan M. (peff)


Lesenswert?

Ich habe das Ganze jetzt noch einmal genauer beobachtet, die letzten 
Tage.
Es hängt definitiv mit der WLAN-Stärke, wenn vorhanden, zusammen.

Der Sensor, der bei -55dB liegt, läuft sein nunmehr über 20 Tagen durch.
Der Sensor, der bei um die -70dB liegt, hatte das Phänomen 2x...
Der Sensor, der bei um die -80dB liegt, hatte das Phänomen 3x...

Debuggingmode Wi-Fi über die IDE fördert auch keine wirklichen 
Erkenntnisse...
Einmal tauchte "no buf for action frame" vor dem Phänomen auf.
Dazu findet man allerdings auch nicht wirklich was.

von Stefan F. (Gast)


Lesenswert?

Probiere mal einen älteren Arduino Core. Version 2.3.0 lief bei mir wie 
gesagt mehr als 2 Jahre durch. Ich habe das Gerät danach abgebaut, weil 
ich es nicht mehr brauchte.

von Stefan M. (peff)


Lesenswert?

Moin Zusammen,

habe das Thema nun im Griff.
Zwei Punkte haben wesentlich zu Verbessrung/Behebung des Problems 
beigetragen.

Punkt 1:
Ich rufe nur noch WiFi.begin() zum wieder verbinden auf.
Alles andere wie Hostname, Wifi.mode() oder auch WiFi.persistent() werde 
nur einmal im Setup eingestellt.
Die Werte bleiben trotz WiFi.disconnect(true) erhalten.

Punkt 2:
Wohl der ausschlaggebendste Punkt.
Deaktivierung der automatischen Funkkanal-Einstellung in der Fritz!Box
Mir war aufgefallen, dass die Probleme zumeist auftraten, wenn sich der 
Kanal zwischen Deaktivierung und Aktivierung des WiFis am ESP geändert 
hatte.

Interessant ist weiterhin, dass diese Probleme nur in Funk-Bereichen mit 
schwacher WiFi Ausleuchtung auftraten und nur bei ESP8266ern.

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
Noch kein Account? Hier anmelden.