Per definizione una IRQ DEVE essere la più breve possibile e NON dovrebbe neanche usare la seriale, figuriamoci fare altre cose.
Un modo pratico è quello di utilizzare una flag ... quando scatta la IRQ semplicemente la flag viene messa a true, poi, nel loop(), che deve girare sempre senza ritardi, si controlla la flag e se vera, si fa quello che si deve fare e la si rimette falsa.
Ok ho capito il concetto, la flag si intende una variabile?
Quando scatta interrupt irq mette la variabile flag a True, nel loop quando la variabile flag è True eseguo il mio codice e le mie operazioni e la rimetto in false, giusto?
Ho seguito tutti i consigli e settato il codice che riporto di seguito nel caso possa tornare utile a qualcuno:
#include <SPI.h>
#include <AS3935.h>
#include <ESP8266WiFi.h> //per gestire WifiClientSecure (collegamento ad xyz.it)
#include <WiFiClient.h> //per gestire la connessione alla rete Wifi
//dati per la connessione alla rete Wifi
const char* MY_SSID = "xxx";
const char* MY_PWD = "yyy";
//dati per la connessione ad xyz.it
const char* host = "www.xyz.it";
const uint16_t port = 443;
int distanza_fulmine;
bool variabile_flag = false; //variabile che diventa true solo quando viene rilevato un fulmine
void printAS3935Registers(); //rileva e stampa i parametri del sensore (rumore di fondo, spike rejection, soglia di controllo)
byte SPItransfer(byte sendByte); //funzione che si occupa del traferimento dei dati via SPI
int valore_calibrazione;
void AS3935Irq(); //funzione che verifica se ci sono disturbi o fulmini e causa l'interrupt
AS3935 AS3935(SPItransfer,D4,D3); //primo parametro: funzione per il trasferimento dei dati via SPI
//secondo parametro: pin CS collegato ad Arduino
//terzo parametro:pin IRQ collegato ad Arduino
void setup(){
Serial.begin(9600);
//connessione Wifi
connectWifi();
SPI.begin();
SPI.setDataMode(SPI_MODE1);
SPI.setClockDivider(SPI_CLOCK_DIV16);
SPI.setBitOrder(MSBFIRST);
AS3935.reset(); //ripristina tutti i valori di registro interni ai valori predefiniti
delay(10);
AS3935.setOutdoors(); //setta il sensore per il funzionamento all'esterno
AS3935.registerWrite(AS3935_NF_LEV,2); //scrive 2 nel Noise Level register
//se il sensore non riesce a stare nel range di tolleranza la calibrazione non andrà a buon fine e restituirà false
if(!AS3935.calibrate()) {
Serial.println("La calibrazione non è andata a buon fine, controllare il cablaggio");
}
valore_calibrazione=AS3935.registerRead(AS3935_TUN_CAP); //il range è compreso tra 0 e 15
Serial.print("La calibrazione rilevata è (range concesso tra 0 e 15): ");
Serial.println(valore_calibrazione);
//AS3935.enableDisturbers(); //turn on indication of distrubers, once you have AS3935 all tuned, you can turn those off with disableDisturbers()
AS3935.disableDisturbers();
printAS3935Registers(); //rileva e stampa i parametri del sensore (rumore di fondo, spike rejection, soglia di controllo)
//usare interrupt significa che non serve controllare lo stato del pin continuamente, lo fa il chip da solo
attachInterrupt(digitalPinToInterrupt(D3), AS3935Irq, RISING);
}
void loop(){
if (variabile_flag) { //diventa true quando viene rilevato un fulmine
//collegamento all'host xyz.it
WiFiClientSecure client;
client.setInsecure(); //non si utilizzano certificati di sicurezza
//verifica se il collegamento non è andato a buon fine
if (!client.connect(host, port)) {
delay(5000);
return;
}
//se la connessione all'host xyz.it è avvenuta
if (client.connected()) {
String url1 = "GET /aggiungi_fulmini.php?distanza_fulmine=";
String url2 = " HTTP/1.1";
//Serial.print(url1);
//Serial.print(distanza_fulmine, DEC);
//Serial.println(url2);
//invio url all'host xyz.it per il salvataggio dei dati sul database mysql
client.print(url1);
client.print(distanza_fulmine, DEC);
client.println(url2);
client.println("Host: www.xyz.it");
client.println("Access-Control-Allow-Origin: *");
client.println("Connection: close");
client.println();
client.stop();
}
variabile_flag= false;
}
}
void printAS3935Registers(){
int noiseFloor = AS3935.getNoiseFloor();
int spikeRejection = AS3935.getSpikeRejection();
int watchdogThreshold = AS3935.getWatchdogThreshold();
//Serial.print("Il rumore di fondo è: ");
//Serial.println(noiseFloor,DEC);
//Serial.print("Lo spike rejection è: ");
//Serial.println(spikeRejection,DEC);
//Serial.print("La soglia di controllo è: ");
//Serial.println(watchdogThreshold,DEC);
}
byte SPItransfer(byte sendByte){
return SPI.transfer(sendByte);
}
ICACHE_RAM_ATTR void AS3935Irq(){ //ICACHE_RAM_ATTR serve per caricare nella ram altrimenti con esp non funzionano gli interrupt
//verifica cosa ha causato l'interrupt
//appena leggiamo l'interrupt, il pin IRQ diventa LOW
int irqSource = AS3935.interruptSource(); //restituisce bit 0: livello rumore troppo alto
// bit 2: rilevato disturbo
// bit 3: rilevato fulmine
//if (irqSource & 0b0001){
// Serial.println("Livello rumore troppo alto");
//}
//if (irqSource & 0b0100){
// Serial.println("Disturbo rilevato");
//}
if (irqSource & 0b1000){
distanza_fulmine = AS3935.lightningDistanceKm(); //determina la distanza del fulmine in km
if (distanza_fulmine < 41 && distanza_fulmine > 0){ //40 km è la distanza di rilevamento massima
//Serial.print("Fulmine rilevato a ");
//Serial.print(distanza_fulmine,DEC);
//Serial.println(" km");
variabile_flag = true;
}
}
}
//funzione per la connessione alla rete wifi
void connectWifi()
{
WiFi.begin(MY_SSID, MY_PWD);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
Serial.println("Connesso");
}
Approfitto per chiedere una ultima cosa: ho notato che il codice, funzionante, quando lo trasmetto alla scheda a volte non si avvia e devo spegnerla e riaccenderla o resettarla pù volte e poi funziona senza problemi. A cosa può essere dovuto?
... premesso che io ho abbandonao da molto tempo gli ESP8266 a favode dei molto più performati ed affidabili ESP32 (ormai li trovi praticamente allo stesso prezzo e, volendo nello stesso formato di schede), comunque è strano.
Io ho preso da tantissimo tempo l'abitudine di mettere un delay(500) subito come prima cosa all'inizio del setup() (tanti anni fa, con i vecchi arduino, se si usava la seriale, era meglio farlo) e ... non ho mai avuto problemi ... puoi provare, ma se non risolvi ... potrebbe essere qualche problema nel codice o qualche difetto delle schede ...
Potresti mettere qualche Serial.println() di diagnostica in vari punti e capire dove si ferma ...