Forum: Mikrocontroller und Digitale Elektronik ESP8266 crash während updateWifi() - ist millis() das Problem?


von Christian K. (Gast)


Lesenswert?

Ich programmiere den ESP8266 mit Arduino. Das Program funktioniert 
einwandfrei solange der ESP über Wifi verbunden ist.

Wenn der Accesspoint aber ausgeschaltet ist, läuft im Hintergrund der 
Wifi-Connect weiter und versucht sich zu verbinden, während das Program 
über die GUI benutzt werden kann.

Treten dann Interrupts auf, chrashed das System nach kurzer Zeit.

Unten habe ich mal den Exception decoder output angegeben.

Mir ist aufgefallen, das immer die Funktion
1
millis()
 auf dem Stack ist. Diese Funktion benutze ich auch im Interrupt 
(ansonsten setzt der Interrupt nur ein paar Variablen). Das ist laut 
Arduino docu erlaubt wenn man beachtet das millis() währen des 
Interrupts nicht weiter zählt.

Die Funktion millis)() ruft system_get_time() auf die nicht auf dem 
Stack liegt und ist ansonsten unauffällig.


Gibt es ähnliche Chrash Erfahrungen während updateWifi()? Gibt es 
Erfahrungen mit millis() in Interrupt Routinen?

1
unsigned long ICACHE_RAM_ATTR millis()
2
{
3
  union {
4
     uint64_t  q;     // Accumulator, 64-bit, little endian
5
     uint32_t  a[2];  // ..........., 32-bit  segments
6
  } acc;
7
  acc.a[1] = 0;       // Zero high-acc
8
  uint32_t  m = system_get_time();
9
  uint32_t  c = micros_overflow_count +
10
                   ((m < micros_at_last_overflow_tick) ? 1 : 0);
11
  acc.q  = ( (uint64_t)( m * (uint64_t)MAGIC_1E3_wLO ) >> 32 );
12
  acc.q += ( m * (uint64_t)MAGIC_1E3_wHI );
13
  acc.q += ( c * (uint64_t)MAGIC_1E3_wLO );
14
  acc.a[1] += (uint32_t)( c * (uint64_t)MAGIC_1E3_wHI );
15
  return ( acc.a[1] );  // Extract result, high-acc
16
}


Der ESP8266 Exception Stack decoded:
1
0x40103523: lmacRecycleMPDU at ?? line ?
2
0x40103986: lmacRecycleMPDU at ?? line ?
3
0x40101e0e: trc_NeedRTS at ?? line ?
4
0x4010346a: lmacProcessTxSuccess at ?? line ?
5
0x40106636: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring_digital.c line 136
6
0x401065fc: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring_digital.c line 130
7
0x402459a0: sleep_reset_analog_rtcreg_8266 at ?? line ?
8
0x4020eec5: _printf_common at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf_i.c line 94
9
0x40212ec4: __ssputs_r at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf.c line 180
10
0x4020eec5: _printf_common at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf_i.c line 94
11
0x40100f22: pp_post at ?? line ?
12
0x40104304: lmacTxFrame at ?? line ?
13
0x40103523: lmacRecycleMPDU at ?? line ?
14
0x40212ec4: __ssputs_r at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf.c line 180
15
0x40103986: lmacRecycleMPDU at ?? line ?
16
0x4020eec5: _printf_common at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf_i.c line 94
17
0x4010346a: lmacProcessTxSuccess at ?? line ?
18
0x4020f280: _printf_i at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf_i.c line 241
19
0x402459a0: sleep_reset_analog_rtcreg_8266 at ?? line ?
20
0x40105744: spi_flash_erase_sector at ?? line ?
21
0x40106890: pvPortZalloc at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/heap.c line 174
22
0x40235c64: wifi_param_save_protect_with_check at ?? line ?
23
0x40235c4d: wifi_param_save_protect_with_check at ?? line ?
24
0x40235d37: system_param_save_with_protect at ?? line ?
25
0x40235d1a: system_param_save_with_protect at ?? line ?
26
0x40236204: wifi_station_ap_number_set at ?? line ?
27
0x40104304: lmacTxFrame at ?? line ?
28
0x40106929: __wrap_spi_flash_read at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_phy.c line 267
29
0x402363fc: wifi_station_ap_number_set at ?? line ?
30
0x402364ce: wifi_station_ap_number_set at ?? line ?
31
0x40245600: sleep_reset_analog_rtcreg_8266 at ?? line ?
32
0x4023649d: wifi_station_ap_number_set at ?? line ?
33
0x40236504: wifi_station_set_config at ?? line ?
34
0x40208ebc: ESP8266WiFiSTAClass::disconnect(bool) at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 558
35
0x40101fe8: wDev_ProcessFiq at ?? line ?
36
0x4023593e: wifi_get_opmode at ?? line ?
37
0x40236aff: wifi_station_get_connect_status at ?? line ?
38
0x40208f24: ESP8266WiFiSTAClass::status() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 558
39
0x40100721: cont_continue at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/cont.S line 51
40
0x40208cb3: ESP8266WiFiMulti::run() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp line 175
41
0x401064ca: millis at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring.c line 183
42
0x40208459: updateWifi() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 723
43
0x4020cd18: esp_yield at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_main.cpp line 91
44
0x402087c5: loop at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 848
45
0x4020cda4: loop_wrapper at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_main.cpp line 125
46
0x40100739: cont_wrapper at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/cont.S line 81

von Kolja L. (kolja82)


Lesenswert?

Schau dir mal die Funktion yield() an,
die könnte die vielleicht helfen

von Christian K. (Gast)


Lesenswert?

0x4020cd18: esp_yield at 
/home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8 
266/core_esp8266_main.cpp  line 91

Wie du siehst ist yield auf dem Stack... D.h. die Wifi library wurde 
durch yield aufgerufen.

von Christian K. (Gast)


Lesenswert?

Habe gerade mit einer vollständig leeren Interrupt Routine (es handelt 
sich um einen external GPIO interrupt) getestet. Sobald ich anfange 
Interrupts auszulösen crashed  updateWifi() nach ein paar Interrupts...

von Christian K. (Gast)


Lesenswert?

Wenn ich den exception Stack richtig interpretiere wurde der erste 
Interrupt-Handler bei Zeile 130 von einem zweiten Interrupt Handler 
unterbrochen. Der zweite Interrupt Handler wurde bei Zeile 136 von dem 
Wifi Stack unterbrochen. Der nur als binary vorliegende Wifi-Stack hat 
noch zwei weitere Funktionen aufgerufen. Dann kam mein leerer Interrupt 
greenKey() und das System ist mit illegal instruction gecrashed...

Alles davor auf dem Stack zeigt, dass der Processor tief im Wifi Stack 
vergraben ist der durch den call nach updateWifi() aufgerufen wurde.
1
Exception 0: Illegal instruction
2
Decoding 49 results
3
0x4020daac: greenKey() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 199
4
0x40103523: lmacRecycleMPDU at ?? line ?
5
0x40103986: lmacRecycleMPDU at ?? line ?
6
0x4010346a: lmacProcessTxSuccess at ?? line ?
7
0x40106636: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring_digital.c line 136
8
0x401065fc: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring_digital.c line 130
9
0x402458b0: sleep_reset_analog_rtcreg_8266 at ?? line 
10
0x40212dd4: __ssputs_r at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf.c line 180
11
0x4020edd5: _printf_common at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf_i.c line 94
12
0x40100f22: pp_post at ?? line ?
13
0x40104304: lmacTxFrame at ?? line ?
14
0x40212dd4: __ssputs_r at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf.c line 180
15
0x4020edd5: _printf_common at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf_i.c line 94
16
0x40212dd4: __ssputs_r at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf.c line 180
17
0x4020f190: _printf_i at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/nano-vfprintf_i.c line 241
18
0x4010106b: ppCalFrameTimes at ?? line ?
19
0x402458b0: sleep_reset_analog_rtcreg_8266 at ?? line ?
20
0x40105744: spi_flash_erase_sector at ?? line ?
21
0x40106890: pvPortZalloc at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/heap.c line 174
22
0x40235b74: wifi_param_save_protect_with_check at ?? line ?
23
0x40235b5d: wifi_param_save_protect_with_check at ?? line ?
24
0x40235c47: system_param_save_with_protect at ?? line ?
25
0x40235c2a: system_param_save_with_protect at ?? line ?
26
0x40236114: wifi_station_ap_number_set at ?? line ?
27
0x40103523: lmacRecycleMPDU at ?? line ?
28
0x40106929: __wrap_spi_flash_read at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_phy.c line 267
29
0x4023630c: wifi_station_ap_number_set at ?? line ?
30
0x402363de: wifi_station_ap_number_set at ?? line ?
31
0x40245510: sleep_reset_analog_rtcreg_8266 at ?? line ?
32
0x402363ad: wifi_station_ap_number_set at ?? line ?
33
0x40236414: wifi_station_set_config at ?? line ?
34
0x40208dc8: ESP8266WiFiSTAClass::disconnect(bool) at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 558
35
0x40207eff: updateLCD() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 625
36
0x4023584e: wifi_get_opmode at ?? line ?
37
0x40236a0f: wifi_station_get_connect_status at ?? line ?
38
0x40208e30: ESP8266WiFiSTAClass::status() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 558
39
0x40208bbf: ESP8266WiFiMulti::run() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp line 175
40
0x401064ca: millis at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring.c line 183
41
0x40208369: updateWifi() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 737
42
0x4020cc24: esp_yield at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_main.cpp line 91
43
0x402086d1: loop at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 862

von Christian K. (Gast)


Lesenswert?

Ich habe jetzt auch mal die Stack Size um 1k vergrößert, hilft nicht...
1
#define CONT_STACKSIZE (4096+1024)

von Michael U. (amiga)


Lesenswert?

Hallo,

da Dein Programm ja unbekannt ist: ich habe hier nur ein ESP8266-Projekt 
in Betrieb, daß einen externen Interrupt nutzt. Der kommt von einem 
RFM12-modul wenn ein gültiges Byte empfangen wurde. Die ISR ist relativ 
lang weil alle 30 Byte komplett eingelesen werden müssen.
WiFi reconnects habe ich hier dank vielen WLANs öfter, gecrasht ist das 
bisher noch nie, allerdings habe ich den AP auch nie längere Zeit 
offline.
Müßte ich mal testen, kann mir im Moment aber eigentlich kein wirkliches 
Problem vorstellen.

Gruß aus Berlin
Michael

von Christian K. (Gast)


Lesenswert?

Ich verstehe gar nicht, warum mein externer Interrupt noch durchkommt. 
In der Funktion interupt_handler in Zeile 134 werden GPIO Interrupt 
disabled... (  ETS_GPIO_INTR_DISABLE(); )


[c]
void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
  (void) arg;
  uint32_t status = GPIE;
  GPIEC = status;//clear them interrupts
  uint32_t levels = GPI;
  if(status == 0 || interrupt_reg == 0) return;
  ETS_GPIO_INTR_DISABLE();
  int i = 0;
  uint32_t changedbits = status & interrupt_reg;
  while(changedbits){
    while(!(changedbits & (1 << i))) i++;
    changedbits &= ~(1 << i);
    interrupt_handler_t *handler = &interrupt_handlers[i];
    if (handler->fn &&
        (handler->mode == CHANGE ||
         (handler->mode & 1) == !!(levels & (1 << i)))) {
      // to make ISR compatible to Arduino AVR model where interrupts 
are disabled
      // we disable them before we call the client ISR
      uint32_t savedPS = xt_rsil(15); // stop other interrupts
      ArgStructure* localArg = (ArgStructure*)handler->arg;
      if (localArg && localArg->interruptInfo)
      {
         localArg->interruptInfo->pin = i;
         localArg->interruptInfo->value = __digitalRead(i);
         localArg->interruptInfo->micro = micros();
      }
      if (handler->arg)
      {
        ((voidFuncPtrArg)handler->fn)(handler->arg);
      }
      else
      {
        handler->fn();
      }
       xt_wsr_ps(savedPS);
    }
  }
  ETS_GPIO_INTR_ENABLE();
}
[\c]

Eben habe ich alles auf die neusten Versionen von git upgedatet, Fehler 
bleibt leider

von Michael U. (amiga)


Lesenswert?

Hallo,

mir ist gerade bewusst geworden, daß Du ja offenbar direkt auf der 
Espressif-Ebene unterwegs bist. Das habe ich mir bisher fast immer 
geschenkt und bin in der "Arduino"-Ebene geblieben. Werde Dir also wohl 
nicht helfen können.
Dein Problem wäre wohl vermutlich im Espressif-Forum besser aufgehoben.

Gruß aus Berlin
Michael

von Christian K. (Gast)


Lesenswert?

Nee, ich debuge nur auf expressif Ebene. Das Program ist pure Arduino.

Ich habe den Source-Code auf das Minimum runtergesripped. Hier der Code:
1
#include <ESP8266WiFi.h>
2
#include <ESP8266WiFiMulti.h>
3
#include <WiFiUdp.h>
4
5
#define DEBUG
6
#ifndef DEBUG  // disable Serial output
7
#define Serial NoDebug
8
  static class {
9
  public:
10
      void begin(...) {}
11
      void print(...) {}
12
      void println(...) {}
13
      void printf(...)  {}
14
      void flush(...)  {}
15
  } Serial;
16
#endif
17
18
ESP8266WiFiMulti wifiMulti;      // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti'
19
20
#define PIN_D0  16  // WAKE
21
#define PIN_D1   5  // User purpose
22
#define PIN_D2   4  // User purpose
23
#define PIN_D3   0  // FLASH mode at boot time
24
#define PIN_D4   2  // TXD1 (Note: low on boot means go to FLASH mode)
25
#define PIN_D5  14  // HSCLK
26
#define PIN_D6  12  // HMISO
27
#define PIN_D7  13  // HMOSI  RXD2
28
#define PIN_D8  15  // HCS    TXD0
29
#define PIN_D9   3  //        RXD0
30
#define PIN_D10  1  //        TXD0
31
32
#define PIN_MOSI 8  // SD1
33
#define PIN_MISO 7  // SD0
34
#define PIN_SCLK 6  // CLK
35
#define PIN_HWCS 0  // D3
36
37
#define PIN_D11  9  // SD2
38
#define PIN_D12 10  // SD4
39
40
// Input-Output Definitions
41
static const byte greenKeyInput = PIN_D2;
42
static const byte redKeyInput   = PIN_D1;
43
static const byte blueKeyInput  = PIN_D0;
44
static const byte LEDPin        = PIN_D4;
45
46
// Wifi States
47
static const int WIFI_IDLE=0;
48
static const int WIFI_CONNECTING=1;
49
static const int WIFI_CONNECTED=2;
50
static int wifiState=WIFI_IDLE;
51
52
void setup() {
53
  // GPIO setupt
54
  pinMode(greenKeyInput, INPUT);
55
  pinMode(redKeyInput, INPUT);
56
  pinMode(blueKeyInput, INPUT_PULLUP);
57
  pinMode(LEDPin, OUTPUT);
58
  digitalWrite(LEDPin, HIGH);
59
60
  Serial.begin(230400);          // Start the Serial communication to send messages to the computer
61
  delay(10);
62
63
  attachInterrupt(digitalPinToInterrupt(greenKeyInput), greenKey, FALLING);
64
  attachInterrupt(digitalPinToInterrupt(redKeyInput), redKey, FALLING);
65
}
66
67
// Interrupt Service Routines
68
void greenKey() {}
69
void redKey() {}
70
71
void updateWifi(void)
72
{
73
  static unsigned long prevMillis=0;
74
  static const unsigned long delayMs=250;
75
76
  switch (wifiState)  {
77
    case WIFI_IDLE:
78
      wifiState=WIFI_CONNECTING;
79
      wifiMulti.addAP("SSID", "Password");   // add Wi-Fi networks you want to connect to      
80
      Serial.println("Wifi Connecting");      
81
    break;
82
    case WIFI_CONNECTING:
83
      if (millis()-prevMillis > delayMs)  {
84
        if (wifiMulti.run() == WL_CONNECTED)  {
85
          wifiState=WIFI_CONNECTED;
86
#ifdef DEBUG
87
          Serial.printf("\nWifi Connected, RSSI=%d", WiFi.RSSI() );
88
          Serial.println("\r\n");
89
          Serial.print("Connected to "); 
90
          Serial.println(WiFi.SSID());   // Tell us what network we're connected to
91
          Serial.print("IP address:\t");
92
          Serial.print(WiFi.localIP());  // Send the IP address of the ESP8266 to the computer
93
          Serial.println("\r\n");
94
          Serial.println("Begin Startup UDP...");
95
#endif                   
96
        }
97
        prevMillis=millis();
98
        Serial.print(".");
99
      }
100
    break;
101
    default:
102
    case WIFI_CONNECTED:
103
        if (wifiMulti.run() != WL_CONNECTED)  {    
104
          wifiState=WIFI_CONNECTING;
105
          Serial.println("Wifi Connection lost, try reconnect!");              
106
        }
107
    break;
108
  }
109
}
110
111
void loop() {
112
  updateWifi();
113
  yield();
114
}

Und hier der Exception Stack nach einigen greenKey() interrupts:
1
Exception 0: Illegal instruction
2
Decoding 45 results
3
0x402044bc: greenKey() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/test/test.ino line 78
4
0x40106646: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring_digital.c line 212
5
0x4010660c: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring_digital.c line 212
6
0x40238100: sleep_reset_analog_rtcreg_8266 at ?? line ?
7
0x40223f03: pp_attach at ?? line ?
8
0x40223f52: pp_attach at ?? line ?
9
0x4010106b: ppCalFrameTimes at ?? line ?
10
0x40238100: sleep_reset_analog_rtcreg_8266 at ?? line ?
11
0x40105744: spi_flash_erase_sector at ?? line ?
12
0x401067f4: pvPortZalloc at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/heap.c line 174
13
0x4022bd94: wifi_param_save_protect_with_check at ?? line ?
14
0x4022bd7d: wifi_param_save_protect_with_check at ?? line ?
15
0x4022be67: system_param_save_with_protect at ?? line ?
16
0x4022be4a: system_param_save_with_protect at ?? line ?
17
0x4022c334: wifi_station_ap_number_set at ?? line ?
18
0x40103523: lmacRecycleMPDU at ?? line ?
19
0x40106a05: __wrap_spi_flash_read at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_phy.c line 267
20
0x4022c52c: wifi_station_ap_number_set at ?? line ?
21
0x4022c5fe: wifi_station_ap_number_set at ?? line ?
22
0x40237d60: sleep_reset_analog_rtcreg_8266 at ?? line ?
23
0x4022c5cd: wifi_station_ap_number_set at ?? line ?
24
0x4022c634: wifi_station_set_config at ?? line ?
25
0x40202f5c: ESP8266WiFiSTAClass::disconnect(bool) at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 558
26
0x40103266: lmacProcessTXStartData at ?? line ?
27
0x40102192: wDev_ProcessFiq at ?? line ?
28
0x40104bfd: ets_timer_disarm at ?? line ?
29
0x4022ba66: wifi_get_opmode at ?? line ?
30
0x4022cc2f: wifi_station_get_connect_status at ?? line ?
31
0x40202fc4: ESP8266WiFiSTAClass::status() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 558
32
0x40100721: cont_continue at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/cont.S line 51
33
0x40202d53: ESP8266WiFiMulti::run() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp line 175
34
0x401064da: millis at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_wiring.c line 183
35
0x40202821: updateWifi() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/test/test.ino line 99
36
0x40204214: esp_yield at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_main.cpp line 91
37
0x402028d1: loop at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/test/test.ino line 131
38
0x402042a0: loop_wrapper at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/core_esp8266_main.cpp line 125
39
0x40100739: cont_wrapper at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.4.2/cores/esp8266/cont.S line 81

von Christian K. (Gast)


Lesenswert?

Ich hoffe mir kann irgend jemand einen Programmierfehler nachweisen, 
denn ansonsten ist wohl die WiFi Library das Problem?

von Marc Horby (Gast)


Lesenswert?

Christian K. schrieb:
> Ich hoffe mir kann irgend jemand einen Programmierfehler
> nachweisen,
> denn ansonsten ist wohl die WiFi Library das Problem?

Wenn du für den ESP die Version 2.4.2 hat, kann es sein!
Bei mir hat WiFi des öfteren sich getrennt und der AutoReconnect nicht 
funktioniert. Bei der Version 2.3.0 hingegen gab es solch ein problem 
nicht.

Downgrade mal über den Boardverwalter den "esp8266 by ESP8266 Community"

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

muß ich mir mal in Ruhe anschauen, ESP8266WiFiMulti.h habe ich bisher 
noch nicht benutzt.

Ich habe mal ein Beispiel von mir unverändert anghängt.
Ist ein WiFi-Client mit einer Glimmanzeige als Thermometer.
Steuerung per MQTT und Ausgabe per PWM.

Das Konstrukt mit dem Ticker stammt aus dem Netz, Grund war eine 
Ungereimtheit mit dem WiFi-Status: die Lib meldet WL_CONNECTED was 
prinzipiell auch stimmt. Der AsyncMQTT hat dann sofort mit dem Borker 
verbunden. Wollte er zumindest... Der ESP hatte noch keine gültige IP 
vom DHCP bekommen und die MQTT-Anmeldung lief ins Leere.

Der ESP war denn sauner im WLAN, der MQTT aber nicht und auch nie wieder 
einen Event zum Verbinden ausgelöst.

Ist jetzt mehr als Erklärung gedacht, Deine Geschichte kann ich mir erst 
morgen im Detail wirklich mal anschauen.

Gruß aus Berlin
Michael

von Timmo H. (masterfx)


Lesenswert?

Hast mal zum Testen den Watchdog aus gemacht?
Soweit ich weiß sollte yield eigentlich den Watchdog triggern, oder du 
machst zum spaß mal ein delay(10) rein (was aber eigentlich das selbe 
tun sollte)

von MWS (Gast)


Lesenswert?

Christian K. schrieb:
> einen Programmierfehler nachweisen

AddAP wird für Wifimulti typischerweise nur einmal für jeden AP in 
setup() aufgerufen, damit wird der AP dem Programm bekanntgemacht. Der 
zyklische Aufruf über loop() -> updatewifi() -> wifi_idle dürfte den 
Speicher zumüllen.

von Christian K. (Gast)


Lesenswert?

MWS schrieb:
> AddAP wird für Wifimulti typischerweise nur einmal für jeden AP in
> setup() aufgerufen, damit wird der AP dem Programm bekanntgemacht. Der
> zyklische Aufruf über loop() -> updatewifi() -> wifi_idle dürfte den
> Speicher zumüllen.

Danke für den Hinweis! Aber leider macht er ja auch nur einmal. Der 
State WIFI_IDLE ist ja nur einmal inital aktiv, danach wird er nicht 
mehr angesprungen. Der State wechselt sofort auf 
wifiState=WIFI_CONNECTING; und nie mehr zurück auf WIFI_IDLE

von Michael U. (amiga)


Lesenswert?

Hallo,

so, ich habe mir jetzt Wifimulti mal etwas angeschaut.
Selten soviele Abstürze gesehen in letzter Zeit. ;)
1
#include <ESP8266WiFi.h>
2
#include <ESP8266WiFiMulti.h> 
3
4
ESP8266WiFiMulti wifiMulti;    
5
6
// WiFi
7
bool wifi_present = false;
8
9
bool WiFiReturns(void);
10
bool WiFiCheck(void);
11
12
//#################################################################
13
14
void setup(void){
15
  Serial.begin(115200);  
16
  delay(10);
17
  Serial.println("\r\nReset");
18
19
  WiFi.mode(WIFI_STA);
20
  wifiMulti.addAP("ESP32", "123456789");   // add Wi-Fi networks you want to connect to
21
  wifiMulti.addAP("ESP8266", "987654321");
22
23
  Serial.println("Connecting ...");
24
  wifiMulti.run();
25
}
26
27
//----------------------------------------------------------------
28
29
void loop(void)
30
{
31
  wifi_present = WiFiCheck(); 
32
}
33
34
// ###############################################################
35
// ---------------------- WiFi-Tools ------------------------------
36
// ###############################################################
37
38
bool WiFiCheck()
39
{
40
  if (!WiFiReturns())
41
  {
42
    if (wifi_present)
43
    {
44
      Serial.println("Keine Verbindung");
45
    }
46
    delay(5);                               // wenn man wifiMulti.run() zu schnell hintereinander aufruft verbindet er nicht immer???
47
    wifiMulti.run();
48
49
    return(false);   
50
  }
51
52
  else if (WiFiReturns() and !wifi_present)
53
  {
54
    Serial.print("\r\nConnected to ");
55
    Serial.println(WiFi.SSID());              // welches Netzwerk
56
    while (WiFi.localIP() == IPAddress(0, 0, 0, 0))
57
    {
58
      yield;                                  // WiFi.localIP() im loop ohne yield(); crasht den ESP
59
    }
60
    Serial.print("IP address:\t");
61
    Serial.println(WiFi.localIP());            
62
63
    return(true);   
64
  }
65
}  
66
67
//----------------------------------------------------------------
68
69
bool WiFiReturns()
70
{
71
  switch (WiFi.status())
72
  {
73
    case WL_NO_SHIELD: return 0;
74
    case WL_IDLE_STATUS: return 0;
75
    case WL_NO_SSID_AVAIL: return 0;
76
    case WL_SCAN_COMPLETED: return 1;
77
    case WL_CONNECTED: return 1;
78
    case WL_CONNECT_FAILED: return 0;
79
    case WL_CONNECTION_LOST: return 0;
80
    case WL_DISCONNECTED: return 0;
81
    default: return 0;
82
  }
83
}

läuft bis jetzt stabil, ich habe mir 2 AP mit ESp8266 und ESP32 gebaut 
weil ich mein lokales WLAN nicht dauern ein- und ausschalten will.
Verbindet mit einem AP, bei Verlust mit einem anderen.
Aus der loop() ist es nicht blockierend solange der ESP selbst nicht 
blockiert.
Ausnahme ist ein delay(5);
Der ESP32 als AP macht hier auch etwas Eigenleben, er braucht "ewig" und 
die DHCP IP auszuliefern.

WiFiReturns() habe ich einem Netzfund entliehen.

Deine Tasteninterrupts mußt Du mal selbst einbauen, ich sehe kein 
Problem, wo die den Ablauf stören sollten.

Vielleicht hilft es erstmal etwas weiter als Anregung.

Noch als Nachtrag: die Event-Handler
WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
scheinen nicht mehr durchgereicht zu werden wenn WiFiMulti eingebunden 
ist

autoReconnect() klappt wohl auch nicht mehr so richtig (da hatte doch in 
der 2.3.0 schonmal jemand drüber geklagt???).

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Christian K. (Gast)


Lesenswert?

Marc Horby schrieb:
> Wenn du für den ESP die Version 2.4.2 hat, kann es sein!
> Bei mir hat WiFi des öfteren sich getrennt und der AutoReconnect nicht
> funktioniert. Bei der Version 2.3.0 hingegen gab es solch ein problem
> nicht.
>
> Downgrade mal über den Boardverwalter den "esp8266 by ESP8266 Community"

Hi Marc,

habe gerade auf die V2.3.0 downgegraded, stürzt genauso ab wie mit der 
V2.4.2...

von Christian K. (Gast)


Lesenswert?

Der Exception Stack sieht auch ziemlich gleich aus... (halt jetzt nur 
V2.3.0)
1
Exception 0: Illegal instruction
2
Decoding 53 results
3
0x40206620: greenKey() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 199
4
0x40106b58: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_wiring_digital.c line 119
5
0x40106b20: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_wiring_digital.c line 113
6
0x4023e680: sleep_reset_analog_rtcreg_8266 at ?? line ?
7
0x40101516: ppEnqueueRxq at ?? line ?
8
0x401012e3: ppProcessTxQ at ?? line ?
9
0x40101982: pp_post at ?? line ?
10
0x40104c44: lmacTxFrame at ?? line ?
11
0x40105471: ets_timer_disarm at ?? line ?
12
0x40103e53: lmacRecycleMPDU at ?? line ?
13
0x401042b6: lmacRecycleMPDU at ?? line ?
14
0x40103d9a: lmacProcessTxSuccess at ?? line ?
15
0x40206686: greenKey() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 226
16
0x40106bbc: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_wiring_digital.c line 135
17
0x40106ba6: interrupt_handler at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_wiring_digital.c line 131
18
0x4023e680: sleep_reset_analog_rtcreg_8266 at ?? line ?
19
0x40105942: spi_flash_erase_sector at ?? line ?
20
0x40106ff8: pvPortZalloc at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/heap.c line 33
21
0x402249a8: wifi_param_save_protect_with_check at ?? line ?
22
0x40224991: wifi_param_save_protect_with_check at ?? line ?
23
0x40224a79: system_param_save_with_protect at ?? line ?
24
0x40224e68: wifi_station_ap_number_set at ?? line ?
25
0x40224fcd: wifi_station_ap_number_set at ?? line ?
26
0x4022507c: wifi_station_ap_number_set at ?? line ?
27
0x402250b8: wifi_station_set_config at ?? line ?
28
0x40207f24: ESP8266WiFiSTAClass::disconnect(bool) at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 510
29
0x40102ba6: wDev_ProcessFiq at ?? line ?
30
0x40105471: ets_timer_disarm at ?? line ?
31
0x40105471: ets_timer_disarm at ?? line ?
32
0x401029fc: wDev_ProcessFiq at ?? line ?
33
0x4020bd00: esp_yield at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_main.cpp line 56
34
0x4020bd7d: __yield at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_main.cpp line 56
35
0x402246e6: wifi_get_opmode at ?? line ?
36
0x40225533: wifi_station_get_connect_status at ?? line ?
37
0x40207f8c: ESP8266WiFiSTAClass::status() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 510
38
0x40207d23: ESP8266WiFiMulti::run() at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp line 156
39
0x4020d2c0: Print::write(unsigned char const*, unsigned int) at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/Print.cpp line 76
40
0x4020b631: Print::write(char const*) at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/Print.cpp line 76
41
0x40206a8c: printTimeTFT(unsigned int, int) at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 639
42
0x40207526: updateWifi() at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 733
43
0x4020bd08: esp_yield at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_main.cpp line 56
44
0x402078a9: loop at /home/user/Projects/LEDMatrix/HSG_Stopuhr/FW/ntp/ntp.ino line 861
45
0x4020bd54: loop_wrapper at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_main.cpp line 56
46
0x40100718: cont_norm at /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/cont.S line 109

von Christian K. (Gast)


Lesenswert?

Es folgt der Workaround/Lösung für das Probem.

Das Problem ist: Der ESP8266 crashed, wenn während Wifi nach einer 
Verbindung zum AP sucht (evtl. länger weil der AP ausgeschaltet ist) 
externe GPIO Interrupts auftreten. Wenn Wifi verbunden ist funktionieren 
die Interrupts einwandfrei.

Wie man an dem Exception Stack sieht, tritt der crash immer in der 
Function WifiMulti.run(), tief im Wifi Stack auf.

Die Lösung/Workaround ist, GPIO interrupts zu disablen wenn die Funktion 
run() aufgerufen wird.
1
  noInterrupts(); 
2
  wifiMulti.run();
3
  interrupts();

geht natürlich nicht, weil der Wifi Stack auch Interrupts braucht.

Wie es dann letztendlich geht steht unten im Code Beispiel. Mit diesem 
Code ist mir bisher kein Crash mehr gelungen.
1
#include <ESP8266WiFi.h>
2
#include <ESP8266WiFiMulti.h>
3
4
#define DEBUG
5
#ifndef DEBUG  // disable Serial output
6
#define Serial NoDebug
7
  static class {
8
  public:
9
      void begin(...) {}
10
      void print(...) {}
11
      void println(...) {}
12
      void printf(...)  {}
13
      void flush(...)  {}
14
  } Serial;
15
#endif
16
17
ESP8266WiFiMulti wifiMulti;      // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti'
18
19
#define PIN_D0  16  // WAKE
20
#define PIN_D1   5  // User purpose
21
#define PIN_D2   4  // User purpose
22
#define PIN_D3   0  // FLASH mode at boot time
23
#define PIN_D4   2  // TXD1 (Note: low on boot means go to FLASH mode)
24
#define PIN_D5  14  // HSCLK
25
#define PIN_D6  12  // HMISO
26
#define PIN_D7  13  // HMOSI  RXD2
27
#define PIN_D8  15  // HCS    TXD0
28
#define PIN_D9   3  //        RXD0
29
#define PIN_D10  1  //        TXD0
30
31
#define PIN_MOSI 8  // SD1
32
#define PIN_MISO 7  // SD0
33
#define PIN_SCLK 6  // CLK
34
#define PIN_HWCS 0  // D3
35
36
#define PIN_D11  9  // SD2
37
#define PIN_D12 10  // SD4
38
39
// Input-Output Definitions
40
static const byte greenKeyInput = PIN_D2;
41
static const byte redKeyInput   = PIN_D1;
42
static const byte blueKeyInput  = PIN_D0;
43
static const byte LEDPin        = PIN_D4;
44
45
// Wifi States
46
static const int WIFI_IDLE=0;
47
static const int WIFI_CONNECTING=1;
48
static const int WIFI_CONNECTED=2;
49
static int wifiState=WIFI_IDLE;
50
51
void setup() {
52
  // GPIO setupt
53
  pinMode(greenKeyInput, INPUT);
54
  pinMode(redKeyInput, INPUT);
55
  pinMode(blueKeyInput, INPUT_PULLUP);
56
  pinMode(LEDPin, OUTPUT);
57
  digitalWrite(LEDPin, HIGH);
58
59
  Serial.begin(230400);          // Start the Serial communication to send messages to the computer
60
  delay(10);
61
62
  attachInterrupt(digitalPinToInterrupt(greenKeyInput), greenKey, FALLING);
63
  attachInterrupt(digitalPinToInterrupt(redKeyInput), redKey, FALLING);
64
}
65
66
// Interrupt Service Routines
67
void greenKey() {}
68
void redKey() {}
69
70
void updateWifi(void)
71
{
72
  static unsigned long prevMillis=0;
73
  static const unsigned long delayMs=250;
74
75
  switch (wifiState)  {
76
    case WIFI_IDLE:
77
      wifiState=WIFI_CONNECTING;
78
      wifiMulti.addAP("SSID", "Password");   // add Wi-Fi networks you want to connect to      
79
      Serial.println("Wifi Connecting");      
80
    break;
81
    case WIFI_CONNECTING:
82
      if (millis()-prevMillis > delayMs)  {
83
        ETS_GPIO_INTR_DISABLE();
84
        bool wifiConnected=wifiMulti.run() == WL_CONNECTED;
85
        ETS_GPIO_INTR_ENABLE();        
86
        if (wifiConnected)  {
87
          wifiState=WIFI_CONNECTED;
88
#ifdef DEBUG
89
          Serial.printf("\nWifi Connected, RSSI=%d", WiFi.RSSI() );
90
          Serial.println("\r\n");
91
          Serial.print("Connected to "); 
92
          Serial.println(WiFi.SSID());   // Tell us what network we're connected to
93
          Serial.print("IP address:\t");
94
          Serial.print(WiFi.localIP());  // Send the IP address of the ESP8266 to the computer
95
          Serial.println("\r\n");
96
          Serial.println("Begin Startup UDP...");
97
#endif                   
98
        }
99
        prevMillis=millis();
100
        Serial.print(".");
101
      }
102
    break;
103
    default:
104
    case WIFI_CONNECTED:
105
        if (wifiMulti.run() != WL_CONNECTED)  {    
106
          wifiState=WIFI_CONNECTING;
107
          Serial.println("Wifi Connection lost, try reconnect!");              
108
        }
109
    break;
110
  }
111
}
112
113
void loop() {
114
  updateWifi();
115
  yield();
116
}

von Timmo H. (masterfx)


Lesenswert?

Oder vielleicht mal den watchdog disablen? Sehe in deinen logs nirgends 
nen reset cause

von Christian K. (Gast)


Lesenswert?

Reset Cause: Invalid Instruction steht ganz oben auf dem Exception 
Stack:

Exception 0: Illegal instruction

Watchdog Reset sieht anders aus.

von Michael U. (amiga)


Lesenswert?

Hallo,

ich kann Dir das so bestätigen

Christian K. schrieb:
> Wie man an dem Exception Stack sieht, tritt der crash immer in der
> Function WifiMulti.run(), tief im Wifi Stack auf.

Das kann ich Dir so bestätigen. Ich habe in meinen obigen Source mal die 
Interrupts für die beiden Tasten eingehängt und kann den Crash erzeugen.

Ich bin da also Deinen Beispiel gefolgt:
1
#include <ESP8266WiFi.h>
2
#include <ESP8266WiFiMulti.h> 
3
4
ESP8266WiFiMulti wifiMulti;    
5
6
// WiFi
7
#define WIFI_WAIT 10                                              // 2,5s Verbindungsversuch, dann ab nach loop()
8
9
bool wifi_present = false;
10
11
bool WiFiReturns(void);
12
bool WiFiCheck(void);
13
14
#define GREEN_KEY_INPUT D2
15
#define RED_KEY_INPUT D1
16
#define LED_PIN D4
17
18
// Interrupt Service Routines
19
void greenKey(void);
20
void redKey(void);
21
22
//#################################################################
23
24
void setup(void){
25
  pinMode(GREEN_KEY_INPUT, INPUT_PULLUP);
26
  pinMode(RED_KEY_INPUT, INPUT_PULLUP);
27
  pinMode(LED_PIN, OUTPUT);
28
  digitalWrite(LED_PIN, HIGH);
29
30
  attachInterrupt(digitalPinToInterrupt(GREEN_KEY_INPUT), greenKey, FALLING);
31
  attachInterrupt(digitalPinToInterrupt(RED_KEY_INPUT), redKey, FALLING);
32
33
  Serial.begin(115200);  
34
  delay(10);
35
  Serial.println("\r\nReset");
36
37
  WiFi.mode(WIFI_STA);
38
  wifiMulti.addAP("ESP32", "123456789");   // add Wi-Fi networks you want to connect to
39
  wifiMulti.addAP("ESP8266", "987654321");
40
41
//  connectToWifi();
42
  Serial.println("Connecting ...");
43
  byte count = 0;
44
  while (!(wifi_present = WiFiCheck()) and (count < WIFI_WAIT)) 
45
  {
46
    count++;
47
    delay(500);    
48
  }
49
  if (count == WIFI_WAIT)                  // timeout
50
  {
51
    Serial.println("Kein WLAN");
52
  }
53
}
54
55
//----------------------------------------------------------------
56
57
void loop(void)
58
{
59
  wifi_present = WiFiCheck(); 
60
}
61
62
void greenKey()
63
{
64
  digitalWrite(LED_PIN, HIGH);
65
}
66
67
void redKey()
68
{
69
  digitalWrite(LED_PIN, LOW);
70
}
71
72
// ###############################################################
73
// ---------------------- WiFi-Tools ------------------------------
74
// ###############################################################
75
76
bool WiFiCheck()
77
{
78
  if (!WiFiReturns())
79
  {
80
    if (wifi_present)
81
    {
82
      Serial.println("Verbindung verloren");
83
    }
84
    delay(5);                               // wenn man wifiMulti.run() zu schnell hintereinander aufruft verbindet er nicht immer???
85
    ETS_GPIO_INTR_DISABLE();
86
    wifiMulti.run();
87
    ETS_GPIO_INTR_ENABLE();
88
    return(false);   
89
  }
90
91
  else if (WiFiReturns() and !wifi_present)
92
  {
93
    Serial.print("\r\nConnected to ");
94
    Serial.println(WiFi.SSID());              // welches Netzwerk
95
    while (WiFi.localIP() == IPAddress(0, 0, 0, 0))
96
    {
97
      yield;                                  // WiFi.localIP() im loop ohne yield(); crasht den ESP
98
    }
99
    Serial.print("IP address:\t");
100
    Serial.println(WiFi.localIP());            
101
102
    return(true);   
103
  }
104
}  
105
106
//----------------------------------------------------------------
107
108
bool WiFiReturns()
109
{
110
//  yield();
111
  switch (WiFi.status())
112
  {
113
    case WL_NO_SHIELD: return 0;
114
    case WL_IDLE_STATUS: return 0;
115
    case WL_NO_SSID_AVAIL: return 0;
116
    case WL_SCAN_COMPLETED: return 1;
117
    case WL_CONNECTED: return 1;
118
    case WL_CONNECT_FAILED: return 0;
119
    case WL_CONNECTION_LOST: return 0;
120
    case WL_DISCONNECTED: return 0;
121
    default: return 0;
122
  }
123
}
Gut zu wissen falls ich das doch mal in der Kombination benutze.
Ich habe auch den Aufruf in setup() für mich nochmal geändert, weil ich 
beim Eintritt in loop() für andere Initialisierungen gern weiß, ob es 
ein WLAN gibt.

PS: Deinen Pin-defines und den static const byte greenKeyInput = PIN_D2;
konnte ich nicht sorichtig folgen, das ist in der IDE doch ohnehin 
zugeordnet. Hat es einen Grund, daß Du SPI auf andere Pins gelegt hast 
und nicht die Standard-HW-Pins 12,13,14,15 genutzt hast?

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Christian K. (Gast)


Lesenswert?

Schön zu hören, ist also ein generelles Problem beim ESP8266. Danke fürs 
ausprobieren.

Die Pin Definition habe ich nur in der Source Code kopiert, weil mein 
Board nicht die GPIO Beschriftung hat sondern die D0...D10 Beschriftung 
und mein Schaltplan die GPIO. Das war für mich einfacher, kann man auch 
rauslöschen.

Die Flash SPI Pins sind sicher auch nicht wichtig:
1
#define PIN_MOSI 8  // SD1
2
#define PIN_MISO 7  // SD0
3
#define PIN_SCLK 6  // CLK
4
#define PIN_HWCS 0  // D3

Es sind die User-SPI Pins die auf 12,13,14,15 gemapped sind.

von Michael U. (amiga)


Lesenswert?

Hallo,

Christian K. schrieb:
> Die Pin Definition habe ich nur in der Source Code kopiert, weil mein
> Board nicht die GPIO Beschriftung hat sondern die D0...D10 Beschriftung
> und mein Schaltplan die GPIO. Das war für mich einfacher, kann man auch
> rauslöschen.

das Problem kenne ich nur zu gut...
Ich benutze normalerweise immer die GPIO-Nummern im Source und habe ein 
schönes ausgedrucktes farbiges einlamniertes Bild des jeweilgen Moduls 
zum verdrahten daneben liegen. :-)

Bei den ESP32 Modulen geht es ohne sowas sowieso nicht richtig, ich habe 
sicher 5 Versionen hier, die zwar versuchen sich an das DevKit zu 
halten, aber sie versuchen es eben manchmal nur.

Gruß aus Berlin
Michael

von Timmo H. (masterfx)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> ich kann Dir das so bestätigen
Ich nicht. Habe gerade deinen Code 1:1 übernommen. WLAN ist nicht 
verbunden (da meine SSID anders ist) und wenn ich den Taster an D2 
Drücke ist alles i.O. Nur etwas modifiziert:
1
void greenKey()
2
{
3
  //digitalWrite(LED_PIN, HIGH);
4
  Serial.println("Switch on D2 pressed");
5
}
Läuft so wie erwartet
PlatformIO 3.6.1, ESP8266 1.7.3 (Core 2.4.1)

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe gerade etwas gegooglet, es gibt das Problem auch im 
Zusammenspiel ESPWebserver und externem Interrupt.
Man findet nur wenig, soviele Leute nutzen externe Interrupts wohl 
nicht.

Timmo H. schrieb:
> Ich nicht. Habe gerade deinen Code 1:1 übernommen. WLAN ist nicht
> verbunden (da meine SSID anders ist) und wenn ich den Taster an D2
> Drücke ist alles i.O. Nur etwas modifiziert:

ähhh, welchen Code jetzt? Ist da etwas unübersichtlich der Thread.

Gruß aus Berlin
Michael

von Timmo H. (masterfx)


Lesenswert?

Michael U. schrieb:
> ähhh, welchen Code jetzt? Ist da etwas unübersichtlich der Thread.
Deinen. 1:1 nur greenKey modifiziert

von Michael U. (amiga)


Lesenswert?

Hallo,

der crasht ja auch nicht mehr.

Es gibt noch ganz wenige Meldungen im Netz zu Problemen mit externem 
Interrupt und z.B. dem ESP8266Webserver.
Scheint wirklich eine race condition zu sein, die ganz unter nicht 
sauber behandelt wird.

Gruß aus Berlin
Michael

von Timmo H. (masterfx)


Lesenswert?

Dann suche ich auch nicht weiter, brauche wenn dann schon etwas was sich 
immer reproduzieren lässt. Läuft jetzt seit 30 Minuten problemlos. Kann 
auch den Taster drücken wie ein verrückter Affe.
Ich meine warum ein Minimalbeispiel, wenn es sich dennoch nicht 
reproduzieren lässt?

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

sorry, das hatte sich mit der Änderung überschnitten und mein Text ist 
dadurch etwas unstimmig geworden...

Kommentiere in WiFiCheck()
1
//    ETS_GPIO_INTR_DISABLE();
2
    wifiMulti.run();
3
//    ETS_GPIO_INTR_ENABLE();

das Abschalten der GPIO-Interrupts aus, dann sollte er wieder crashen.
Man muß ihn wohl währende des Aufrufs von wifiMulti.run(); im richtigen 
Moment erwischen, es passiert nicht immer.
Zum Testen könnten man den Code vermutlich noch stark kürzen, ich (und 
der TO) wollte ja was stabil spielendes...

Gruß aus Berlin
Michael

von Timmo H. (masterfx)


Lesenswert?

Michael U. schrieb:
> Hallo,
>
> sorry, das hatte sich mit der Änderung überschnitten und mein Text ist
> dadurch etwas unstimmig geworden...
>
> Kommentiere in WiFiCheck()//    ETS_GPIO_INTR_DISABLE();
>     wifiMulti.run();
> //    ETS_GPIO_INTR_ENABLE();
>

Negativ. Bekomme keinen Absturz provoziert

EDIT... Ahh doch. Aber ist wie erwartet ein wdt reset
1
Exception (0):
2
epc1=0x40201f24 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
3
4
ctx: cont
5
sp: 3ffef320 end: 3ffef880 offset: 01a0
6
7
>>>stack>>>
8
3ffef4c0:  401064b2 feefeffe feefeffe feefeffe
9
3ffef4d0:  c0017025 feefeffe 00000000 4000050c
10
3ffef4e0:  00000000 00000000 0000001f 00000022
11
3ffef4f0:  3fffc200 40106478 3fffc258 4000050c
12
3ffef500:  400043da 00000030 00000016 ffffffff
13
3ffef510:  400044ab 3fffc718 3ffef600 08000000
14
3ffef520:  60000200 08000000 00000003 00000000
15
3ffef530:  0000ffff 00042035 00002035 003fd000
16
3ffef540:  402391f0 0000049c 003fd000 00000030
17
3ffef550:  feefeffe feefeffe feefeffe feefeffe
18
3ffef560:  feefeffe feefeffe feefeffe feefeffe
19
3ffef570:  feefeffe feefeffe feefeffe feefeffe
20
3ffef580:  feefeffe feefeffe feefeffe feefeffe
21
3ffef590:  feefeffe feefeffe feefeffe feefeffe
22
3ffef5a0:  feefeffe feefeffe feefeffe feefeffe
23
3ffef5b0:  feefeffe feefeffe feefeffe feefeffe
24
3ffef5c0:  00000002 4000444e 4021b9bf 00000001
25
3ffef5d0:  ffffffff 00000000 3ffe9081 00000008
26
3ffef5e0:  00000000 4000444e 3fff099c 00000000
27
3ffef5f0:  00000002 4010544f 00000001 60000200
28
3ffef600:  00000002 4000410f 00001001 00000205
29
3ffef610:  3fffc718 40004a3c 000003fd 402391f0
30
3ffef620:  3fffc718 401056e0 000003fd 40106b98
31
3ffef630:  402228ac 000003fd 7fffffff 40222895
32
3ffef640:  3fff0e3c 4022297f 3fff099c 0000049c
33
3ffef650:  000003fd 3ffef720 3fff099c 40222962
34
3ffef660:  ffffff00 55aa55aa 000007da 00000020
35
3ffef670:  00000020 000000db 000000db aa55aa55
36
3ffef680:  000003ff 40222e4c 3fff099c 3fff099c
37
3ffef690:  00000001 00000030 0000001e ffffffff
38
3ffef6a0:  40106b25 00000001 3fff09ac 40223044
39
3ffef6b0:  3ffee470 3fff099c 00000001 3ffef720
40
3ffef6c0:  3ffef740 3fff09d3 000007da 00000020
41
3ffef6d0:  3fff0a5c 3ffef781 00000001 40223116
42
3ffef6e0:  3ffef720 40238e50 000000fe fffffffe
43
3ffef6f0:  3fff0d9c 3ffef740 3fff099c 402230e5
44
3ffef700:  3fff099c 4022314c 00000000 00000000
45
3ffef710:  402026d4 3ffef7b0 3ffef7b0 402030e3
46
3ffef720:  3fff0900 0000001e 3ffef7b0 4020312f
47
3ffef730:  00000000 00000023 3ffef7b0 40203161
48
3ffef740:  3ffef700 3ffef7cc 3ffef7b0 402031d5
49
3ffef750:  3ffefa94 000000ed 000000ed 4010020c
50
3ffef760:  4022257a 00000000 3ffee7d8 00000001
51
3ffef770:  40223747 3ffee7d8 40203314 3ffee860
52
3ffef780:  3fff037c 4020273c 00000000 4020134b
53
3ffef790:  3ffef7b0 3ffee7d8 00000000 402024cb
54
3ffef7a0:  3ffef7c4 3ffef7d0 0000002e 3ffee848
55
3ffef7b0:  00000000 00000000 00000000 00000030
56
3ffef7c0:  40104a4e 00000003 3fff09f8 ffffffc5
57
3ffef7d0:  40100800 3ffeda28 0160befb 00000000
58
3ffef7e0:  40104cdc 0160cb88 3ffef8d0 00000000
59
3ffef7f0:  3ffee1f0 3ffee7cc 3ffee860 3ffef8d0
60
3ffef800:  3fffdad0 3ffee850 40203314 3ffee860
61
3ffef810:  40201356 00000005 00000005 3ffee850
62
3ffef820:  3fffdad0 00000000 00000000 40201fa4
63
3ffef830:  3ffe8958 3ffee850 3ffee824 40202eb4
64
3ffef840:  40201356 000001f4 3ffee824 40202f00
65
3ffef850:  3fffdad0 00000000 3ffee848 4020212c
66
3ffef860:  3fffdad0 00000000 3ffee848 40203360
67
3ffef870:  feefeffe feefeffe 3ffee860 40100700
68
<<<stack<<<
69
70
 ets Jan  8 2013,rst cause:2, boot mode:(1,6)
71
72
73
 ets Jan  8 2013,rst cause:4, boot mode:(1,6)
74
75
wdt reset

: Bearbeitet durch User
von Christian K (Gast)


Lesenswert?

Dann decodiere mal den exception stack...

WD reset kommt immer irgendwann

von Michael U. (amiga)


Lesenswert?

Hallo,

Timmo H. schrieb:
> EDIT... Ahh doch. Aber ist wie erwartet ein wdt reset

warum erwartest Du da einen wdt reset?
Der Programmablauf liefert dazu keinerlei Anlaß.

Gruß aus Berlin
Michael

von Timmo H. (masterfx)


Lesenswert?

Okay tritt auch mit  ESP.wdtDisable(); Müsste man sich ggf. mal den 
ESP8266WiFiMulti::run(void) code genauer ansehen

Michael U. schrieb:
> Hallo,
>
> Timmo H. schrieb:
>> EDIT... Ahh doch. Aber ist wie erwartet ein wdt reset
>
> warum erwartest Du da einen wdt reset?
> Der Programmablauf liefert dazu keinerlei Anlaß.
>
> Gruß aus Berlin
> Michael
Ich kannte anfangs den Code nicht (da verheimlicht) und ein 
while(irgendwas) blubb(); triggert den wtd nicht, ein delay hingen 
schon. (lag of info)

: Bearbeitet durch User
von Christian K (Gast)


Lesenswert?

wdt schlägt immer zu wenn nicht regelmässig zurückgesetzt, also auch 
nach einem Crash.

Darum tritt er auch hier auf. Die Ursache ist aber der Crash und nicht 
das Program

von Michael U. (amiga)


Lesenswert?

Hallo,

auch hier Zustimmung.

@ Timmo H.: ESP.wdtDisable(); stoppt nur den Sofware-Watchdog.
Der Hardware-Watchdog schlägt in jedem Fall nach rund 6s zu wenn der 
nicht von den internen ESp-Routinen zurückgesetzt wird.

PS und völlig OT: 1979 ging hier in der Ex-DDR eine Honeywell-Anlage in 
Betrieb, da gab es auch einen Watchdog, den man beim Laden der Software 
vom tape abschalten mußte.
Es wurde hier vor Ort eine Übersetzung der Kurzanleitung in Auftrag 
gegeben.
Punkt a:
...
Punkt m: kill the watchdog
usw.

Was kam dann vom Übersetzer zurück?
Punkt m: töte den Wachhund ???

Gruß aus berlin
Michael

von Christian K. (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe das ganze Dilemma mit external Interrupts mal dokumentiert 
(siehe Anhang).

Hilft hoffentlich jemand, zumindest ich verstehe damit in einem Jahr 
noch warum der Code so aussieht :-)

von Christian K. (Gast)


Angehängte Dateien:

Lesenswert?

Habe noch ein paar Updates gemacht

von Michael U. (amiga)


Lesenswert?

Hallo,

schön gemachte Doku, Danke.

Darf man fragen welche Art Projekt das ist, was Du da verfolgst?
Mir fällt im Moment nichts ein, wo ich eine wechselnde Verbindung zu 
verschiedenen AP brauche und parallel auch noch mit Hardware-Interrupts 
relativ kurzer Dauer konfrontiert wäre.

Ist nur Neugier...

Gruß aus Berlin
Michael

von Christian K. (Gast)


Angehängte Dateien:

Lesenswert?

Es handelt sich um eine Stop-Uhr, die elektronisch (per Lichtschranken) 
gestartet und gestoppt werden soll.

Die echte Uhr läuft auf dem ESP8266 und schickt die Start- und Stop-Zeit 
zu der LED-Anzeige via WiFi. Der AP ist im LED-Display (raspberry)

Die externen Interrupts müssen die Signale von den Lichtschranken 
zuverlässig erfassen.

Da die Genauigkeit 1/100 Sekunde (10ms) betragen soll müssen die Signale 
als Interrupt erfasst werden (polling ist zu ungenau).

Aber die Interrupt-Rate ist gering, daher funktionieren für mein Project 
alle die Workarounds die ich im Dokument beschrieben habe.

von Michael U. (amiga)


Lesenswert?

Hallo,

ok, trotzdem eine Frage: warum WiFiMulti und kein normaler Connect? 
Wechseln denn die AP, daß Du die Listenverwaltung da brauchst?

Ich hatte mich mit meinem Bekannten übder das Problem unterhalte. Der 
hat z.B. einen Dimmer mit ESP8266 und MQTT laufen. Der Dimmer macht 
Phasenanschnitt mit den 5Hz als Hardware-Interrupt. Der hängt natürlich 
immer im gleichen WLAN. Bei reconnects ist da noch nie was abgestürzt. 
Hätte er bemerkt, wenn plötzlich seine Wohnzimmerlampe ausgegangen wäre, 
weil der ESP als default natülich das Licht ausmacht.

Bei mir habe ich jetzt mal meine Abfragen incl. Deiner IRQ-Sperre in den 
Streamplayer mit ES32 reingebuat. Reconnect klappt zumindest 
zuverlässig, meine WLAN-Umgebung sordt da leider manchmal dafür. Gibt 
logischerweise einen Aussetzer, weil der Ram-Buffer auch auf einem ESP32 
da knapp ist.
Er braucht meist weniger als 1 Sekunde für reconnect, Stream neu 
aufrufen und MP3 syncronisieren, dann spielt er wieder.

Grund fpr WiFimulti ist eigenlich nur, daß ich den Player öfter mal mit 
zu meinem Bekannten nehme wenn wir an der Software rumbasteln. Da 
brauche ich dann nicht die WLAN-Daten anpassen, weil er mit in der 
AP-Liste steht.

Christian K. schrieb:
> Da die Genauigkeit 1/100 Sekunde (10ms) betragen soll müssen die Signale
> als Interrupt erfasst werden (polling ist zu ungenau).

müßte ich glatt mal mit rumspielen wie sich Ticker.h z.B. mit 2ms 
Aufruffolge benimmt..
Eigentlich braucht Du an der Stelle doch nur einen gültigen timestamp?
Also eine Variable im Ticker hochzählen und beim ext. Trigger den Wert 
in eine andere kopieren. Die außen auswerten und wieder auf 0 setzen.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Christian K. (Gast)


Lesenswert?

Ich habe jetzt die Nase voll von den externen Interrupts. Heute war die 
Uhr das erste mal im Einsatz, drei Abstürze auf den Tag verteilt, obwohl 
WiFi connected war.

Ich habe jetzt gerade die SW auf ticker() umgestellt. Hoffe das ist 
stabiler.

von Christian K. (Gast)


Lesenswert?

So zweiter Einsatz-Tag der Stopp-Uhr ist vorbei, es sind keine Abstürze 
mehr aufgetreten.

Mein Fazit: ESP8266 Wifi Stack verträgt sich nicht mit (externen) 
Interrupts. In Klammern, weil auf einer anderen Seite habe ich auch über 
Probleme mit Timer Interrupts und Wifi beim ESP8266 gelesen...

von Michael U. (amiga)


Lesenswert?

Hallo,

Christian K. schrieb:
> So zweiter Einsatz-Tag der Stopp-Uhr ist vorbei, es sind keine Abstürze
> mehr aufgetreten.

Danke für die Info und schön wenn es jetzt klappt.

Deine Schlußfolgerung nehme eher zur Kenntnis, ich muß mal schauen, was 
mein Bekannter da z.B. bei seinem Dimmer gemacht hat.
Das ein ESP8266 immer für Überraschungen gut ist, bestätige ich Dir aber 
auf jeden Fall. Dazu kommt die Einbindung in die ArduinoIDE, die auch 
nicht absolut fehlerfrei ist.
Mit dem ESP32 kann man das Überraschungspotenzial zur Zeit aber noch 
beachtlich vergrößern. ;-)

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Christian K. (Gast)


Lesenswert?

Ich kann das in einem einfachen Szenario jetzt auch nicht nachstellen. 
Im einfachen Szenario habe ich eine UDP Verbindung und schicke alle 
100ms ein Paket raus. Gleichzeitig läuft ein mit 10kHz gepulster externe 
Interrupts und nichts crashed (natürlich nur solange WiFi verbunden 
ist).

In der echten SW habe ich allerdings zwei UDP Verbindungen auf 
verschiedene Ports parallel und asynchron laufen, das kann ich jetzt 
nicht so einfach mit einer vereinfachten SW nachstellen

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.