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!