Wemos D1 mini crash durante esecuzione

Salve. Chiedo il vostro aiuto perchè le mie ricerche online non hanno dato risultati.
Ho realizzato uno sketch per una Wemos D1 mini. Funziona tutto come mi aspetto ma, dopo un tempo variabile da 30 a 180 sec il monitor seriale mi indica un Excepition. Ho installato il plugin ESP Excepition Decoder ma non sono in grado di comprenderne l'output.
Sono consapevole che lo sketch non è molto "elegante", sono all'inizio e sto copiando e adattando vari esempi. In questo caso, utilizzando un encoder ottico, devo leggere il senso di rotazione di un nastro trasportatore ed inviare un dato via wifi quando il nastro gira.

digita o incolla il codice qui
```#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
StaticJsonDocument<200> doc;

#include "arduino_secret.h" 
char ssid[] = SECRET_SSID; 
char pass[] = SECRET_PASS; 


unsigned long lastReconnectMillis = 0;   // variabile per istruzione riconnessione al wifi

int status = WL_IDLE_STATUS;
char serverbase[40] = "script.google.com";  
char server[40];
String path = "";  
String pathbase = "/macros/s/AKfycbxMxhvA0JcNp-g7ToK_wmqslsLI5aM53B-MMy5B9e2qxVbL-eG3mE1R2b2A0qElM1lX/exec?";
int stato;
int nrscheda;
 
WiFiClientSecure client;

 #define sensorA 12
 #define sensorB 13
                            // blocco assegnazioni sketch encoder
int counter2=0;
int counter3 = 0;
String currentDir = "";
String lastDir = "";
String statopressa = "";
String laststatopressa = "";
int primociclo = 0;
unsigned long lap;
unsigned long start;
boolean sign;
int cycling;
int skip;                                            

ICACHE_RAM_ATTR void ai0()      
  {
    sign=true;
    if(digitalRead(sensorB)==LOW) {
    currentDir = "ACW";
    }else{
     currentDir = "CW";
    }  
  }

ICACHE_RAM_ATTR void ai1()       
  {
    sign=true;
    if(digitalRead(sensorA)==LOW) {
    currentDir = "CW";
    }else{
     currentDir = "ACW";
    }
  }

void setup() {    
                                                                          // Setup Serial Monitor
   Serial.begin(115200);
   while (!Serial) {                                                      // TOGLIERE
   delay(1);
   }


  WiFi.mode(WIFI_STA);
   WiFi.begin(ssid, pass);
             
   while (WiFi.status() != WL_CONNECTED) {
   delay(500);
                                Serial.print(".");
   }
                                Serial.println("Connected to wifi");     // TOGLIERE
  


                            // inizio blocco setup sketch encoder 
 
  pinMode(sensorA, INPUT_PULLUP);
  pinMode(sensorB, INPUT_PULLUP);
  
   attachInterrupt(digitalPinToInterrupt(sensorA), ai0, RISING);
   
   attachInterrupt(digitalPinToInterrupt(sensorB), ai1, RISING);
 
   counter3 = 0;    
   cycling = 1;

//----------------------------------------------------------------
   nrscheda = 2;            // ASSEGNARE UN NUMERO ALLA SCHEDA DA 1 A NN (saltare il nr 11)
//----------------------------------------------------------------
 
}                           // fine setup

void loop() {

 if(WiFi.status()!=WL_CONNECTED && millis()-lastReconnectMillis>10000)   // riconnessione se wifi
 {
  lastReconnectMillis=millis();
  WiFi.reconnect();     
 }

  switch(stato){
    case 0:
      //attendo responso ciclo encoder
      waitcmd();     
      break;
    case 1:
      //chiamo l'indirizzo
      call();
      break;                    
    case 2:
      //leggo il codice della risposta e decido come rpocedere (200, 302, 404, 500...)
      getHeader();
      break;
    case 3:
      //leggo dati 
      readdata();
      break;
    case 10:      
      errore();
      break;
  }
}

boolean FIRST = true;       
void go(int st){
  stato = st;
  FIRST = true;             
  delay(300);
}

void errore() {
  if (FIRST) {    
                                                                           
    FIRST = false;    

           client.flush();                    // pulisce i dati
           go(0);                             // ripete il ciclo
  }
}


void waitcmd() {
  
    cycling = 1;
    start = millis();
    lap = millis();
    skip = 0;
    sign = false;   
    
    invioDati();
    
    if (cycling == 2) {

    path = pathbase+"idScheda="+nrscheda+"&parziale="+primociclo+"&stato="+statopressa;         // MODIFICA PUNTATORE aggiungere 
    strncpy(server, serverbase, 40);                                                                    
    
    go(1);      
    }
  }

void call() {
      client.setInsecure();          
                                                  
  if (client.connect(server, 443)) {
                                                  Serial.println("connesso");
                                                  Serial.println(path);  
    client.println("GET "+path+" HTTP/1.1");
    client.println("Host: "+String(server));
    client.println("Connection: close");
    client.println();
    go(2);
  }
}

int requestCode;

void getHeader() {

  if (client.connected()) {
    String line = client.readStringUntil('\n');
                                                
    
    if (line.indexOf("HTTP/1.1") >= 0) {   
      requestCode = getRequestCode(line);
      
    } else if ((requestCode == 302) && (line.indexOf("Location:") >= 0)) {
      int pos = line.indexOf(" ");
      String newaddr = line.substring(pos+1);

      int s = line.indexOf("//")+2;
      int f = line.indexOf("/", s) + 1;
      String str = line.substring(s, f);
      str.toCharArray(server, str.length());
                                                
      path = line.substring(f-1);
                                                
      
    } else if (line.indexOf("Connection: close") >= 0){
                                                    
      if ((requestCode == 302) || (requestCode == 307)) {
        //redirect  
        client.flush();
        go(1);
      } else if (requestCode == 200){
        //leggo i dati  
        go(3);
      } else {
        //non gestito
                                                              
        client.flush();
    
      }
    }
  }
}

int getRequestCode(String line) {
  int n = 0;
  char ll[100] = ""; 
    line.toCharArray(ll, line.length());
    int i = 0;
    char* token = strtok(ll, " ");
    while (token != NULL) {
        i++;        
        token = strtok(NULL, " ");
        if (i == 1) {  
          n = atoi(token);                                //qui ho il codice della risposta (es. 200, 302, ecc.)
        }        
    }  
    return n;
}


int linea;
void readdata(){
 
  if (FIRST) {    
                                                           // Serial.println("Lettura dati");
    FIRST = false;
    linea = 0;
  }
  
    if (client.connected()) {
    
    String line = client.readStringUntil('\n');
    if (linea == 3) {
                                                        
                                                                         // analizzo i dati json
      char json[100];
      line.toCharArray(json, line.length());
      DeserializationError error = deserializeJson(doc, json);
                                                                         // Test if parsing succeeds.

      if (error) {
                                                           Serial.print(F("deserializeJson() failed: "));
                                                           Serial.println(error.f_str());
        go(10);                                                 
      } else {
                                                                          //fetch value
        const char* status = doc["status"];
   // Print values.
                                                            //Serial.print("status: ");
                                                            //Serial.println(status);
          
          go(0);                             // go(0)   ripete il ciclo
      }          
    }    
    linea++; 
  }
 }

   // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

   void invioDati() {
  
  counter2=3;                         // il primo ciclo l'encoder vede sempre lastDir != current Dir con questo sistema 
                                      // si imbroglia il codice             
 
   while (cycling < 2) {  

   attachInterrupt(digitalPinToInterrupt(sensorA), ai0, RISING);
   
   attachInterrupt(digitalPinToInterrupt(sensorB), ai1, RISING);
                                           
  
    while (sign!=true) {
      if (millis()-lap>30000) {
      skip = 2;                               
      statopressa="STOP";
      break;
      }
      delay (10);
    }  

   detachInterrupt(digitalPinToInterrupt(sensorA));
   detachInterrupt(digitalPinToInterrupt(sensorB));
                                  
     if (skip != 2) {
     
     lap = millis();
                                               Serial.println (currentDir);
   
     if (currentDir != lastDir) {                   // SE CAMBIA SENSO ROTAZIONE     currentDir <> lastDir

       if (counter2 != 1) {                         // prova 1 RICONOSCE IL RIMBALZO DEL CONTATTO
         counter2 ++;                               // COUNTER2 +1 ("invertito senso di rotazione")
           
         if (counter2 == 4){                        // solo per il primo ciclo rimette il counter2 a 0
          counter2 =0;
         }                  
         start=millis();                  
           
           }  else {                                    
           counter2 = 0;                            // il prossimo ciclo sarà lastDir=currentDir ma per essere sicuri
           counter3 = 0;                            // che non ci siano contatti falsi dovrà rimanere in questo senso
           }                                        // per n volte (counter3)
           
      } else {             // SE currentDir = lastDir

      if (counter2 == 1) {                          // SE PRECEDENTE ESECUZIONE AVEVA RILEVATO INVERSIONE SENSO

        counter3 ++;
                                               Serial.print ("counter3:  ");
                                               Serial.println (counter3);
        if (counter3 > 50 && millis()-start>3000 ) {  // 100 VOLTE sono meno di 1 giro completo di encoder---  && millis()-start>5000
                                                      // && un tempo più lungo di quanto può durare un'inversione del
                                                      // nastro in fase di scarico discensore
           
           primociclo = 1;                            // assegna nr cicli da inviare quando gira il nastro 
         
           statopressa = "RUN";                    // serve per non inviare ogni 30 sec il dato di stop dopo che è andato in "STOP"
           laststatopressa = statopressa;                                       
                                               Serial.print("statopressa:--------------------------------------  ");
                                               Serial.print(statopressa);
                                               Serial.println();                              
           counter2 = 0;                                                           
           counter3 = 0;

           cycling = 2;                            //  =2 esce dal loop e invia il dato.  per=1 debug
   
                                               Serial.println("invio dato");
                                               Serial.println();          
        }
      } else {                                     // SE PRIMA NON AVEVA GIRATO counter2 = 0
                                                   // funzionamento normale
        counter2 = 0;                                                                                                    
        counter3 = 0;
      }
    }
   
   lastDir = currentDir;   
   sign = false;
      
   }  else {                                       // se skip = 2                                
                                               Serial.println("---------------------------------------STOP");
   sign = false;
   lastDir = currentDir;
   lap=millis();
   skip=0;
    if (laststatopressa=="RUN") {
           laststatopressa="STOP";      
           cycling = 2;                            //  =2 esce dal loop e invia il dato.  per=1 debug
          } else {                      
           cycling =1;                             //  se prima era "STOP" non reinvia il dato                                            
          }                             
   }
      sign = false;
     
   // Put in a slight delay to help debounce the reading
   delay(10);
  }                                                // fine WHILE cycling < 2
 }

l'output del decodificatore dello stack è il seguente:

Exception 0: Illegal instruction
PC: 0x402068e8: String::operator=(char const*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\WString.cpp line 283
EXCVADDR: 0x00000000

Decoding stack results
0x4010037a: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring_digital.cpp line 141
0x40100404: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/interrupts.h line 29
0x40100404: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/interrupts.h line 29
0x40100340: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring_digital.cpp line 135
0x40206714: String::copy(char const*, unsigned int) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\WString.cpp line 214
0x40206909: String::operator=(char const*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\WString.cpp line 285
0x40100129: ai0() at C:\Users\barone\Documents\Arduino\gsheets_WEMOS_ARDU_nuovo/gsheets_WEMOS_ARDU_nuovo.ino line 53
0x40100415: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring_digital.cpp line 173
0x40100404: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/interrupts.h line 29
0x401001d0: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x40100340: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring_digital.cpp line 135
0x40211261: sys_timeout_abs at core/timeouts.c line 189
0x401001d0: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x4020740c: delay_end(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring.cpp line 44
0x40206e14: loop_task(ETSEvent*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 205
0x401001d0: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x4021cc28: br_sha384_update at src/hash/sha2big.c line 165
0x4021d4af: sha2small_out at src/hash/sha2small.c line 249
0x401001d0: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x40206714: String::copy(char const*, unsigned int) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\WString.cpp line 214
0x40206909: String::operator=(char const*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\WString.cpp line 285
0x40206714: String::copy(char const*, unsigned int) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\WString.cpp line 214
0x4010015d: ai1() at C:\Users\barone\Documents\Arduino\gsheets_WEMOS_ARDU_nuovo/gsheets_WEMOS_ARDU_nuovo.ino line 63
0x40100415: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring_digital.cpp line 173
0x40100404: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/interrupts.h line 29
0x4010015d: ai1() at C:\Users\barone\Documents\Arduino\gsheets_WEMOS_ARDU_nuovo/gsheets_WEMOS_ARDU_nuovo.ino line 63
0x40100415: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring_digital.cpp line 173
0x40100340: interrupt_handler(void*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring_digital.cpp line 135
0x40207e5d: uart_write(uart_t*, char const*, size_t) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\uart.cpp line 509
0x40205d78: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x40205d84: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 165
0x40205d78: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x40206051: Print::write(char const*) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/Print.h line 62
0x40206231: Print::printNumber(unsigned long, unsigned char) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\Print.cpp line 268
0x402065de: String::changeBuffer(unsigned int) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\WString.cpp line 187
0x40207e5d: uart_write(uart_t*, char const*, size_t) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\uart.cpp line 509
0x40206e94: __esp_yield() at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/core_esp8266_features.h line 92
0x4020749a: __delay(unsigned long) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring.cpp line 54
0x40201615: invioDati() at C:\Users\barone\Documents\Arduino\gsheets_WEMOS_ARDU_nuovo/gsheets_WEMOS_ARDU_nuovo.ino line 312
0x402017ee: waitcmd() at C:\Users\barone\Documents\Arduino\gsheets_WEMOS_ARDU_nuovo/gsheets_WEMOS_ARDU_nuovo.ino line 171
0x40202aac: ESP8266WiFiSTAClass::status() at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp line 634
0x401001d0: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
0x402021b3: loop() at C:\Users\barone\Documents\Arduino\gsheets_WEMOS_ARDU_nuovo/gsheets_WEMOS_ARDU_nuovo.ino line 124
0x40206fb8: loop_wrapper() at C:\Users\barone\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 197

Ho provato a fare mille modifiche ma non cambia nulla. Da notare che lo stesso codice (opportunamente adattato) funziona senza problemi su un Arduino Mkr 1010wifi.
Grazie per il vostro tempo!

Buonasera e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Buonasera. Mi scuso per aver ignorato il passaggio della presentaione. Ho provveduto e intanto ti ringrazio per la pazienza :sweat_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.