Voici le programme que je cherche à mettre en œuvre :
#include <CircularBuffer.hpp>
#define INTERVAL 120
CircularBuffer<float, 3> h_fifo;
const byte rainPin = 34;
unsigned int raincnt = 0;
unsigned long lastSend; .
ICACHE_RAM_ATTR void cntRain() {
raincnt++;
Serial.println("Action... ");
}
void getSendRain() {
float h_total = 0.00;
Serial.println("Execution de la fonction getSendRain().");
lastSend = millis();
// On calcul le niveau depuis la dernière interogation.
float pluie = raincnt * 0.2794; // Nombre d'impulsion multiplié par la hauteur d'eau en mm d'un godet
raincnt = 0; // On réinitialise le compteur.
h_fifo.push(pluie);
Serial.print("Pluie = "); Serial.print(String(pluie)); Serial.println(" mm ");
using index_h = decltype(h_fifo)::index_t;
for (index_h i = 0; i < h_fifo.size(); i++) {
h_total += h_fifo[i];
}
h_total = h_total * 10;
Serial.print("RAINRATE = "); Serial.println(String((int)(round(h_total))));
}
void setup() {
Serial.begin(115200);
Serial.println("Initialisation...");
pinMode(rainPin, INPUT);
attachInterrupt(digitalPinToInterrupt(rainPin), cntRain, FALLING); // CHANGE: Déclenche de HIGH à LOW ou de LOW à HIGH - FALLING : HIGH à LOW - RISING : LOW à HIGH.
lastSend = millis();
}
void loop() {
if ( millis() - lastSend > INTERVAL * 1000 ) {
getSendRain();
}
}
Le montage est fait comme suit :
Lorsque je téléverse, aucuns problèmes par contre lorsque je bascule les godets pour détecter les actions " HIGH / LOW " j'ai très souvent un redémarrage de l'esp32.
Je vous joints l'image du moniteur série lorsque tout roule bien :
essayez avec "ESP32 Dev Module" pour voir si ça change quelque chose. (je n'ai pas regardé le code en détail mais ne mettez pas de print dans une ISR, c'est toujours une mauvaise idée)
J'ai sélectionné la carte ESP32 Dev Module et c'est le même résultat, j'ai basculé le godet une fois et le moniteur série m'a détecté une action et le basculement suivant, l'ESP32 à Reboot avec l'erreur suivante :
Je ne saurai te l'expliquer de façon rigoureuse, il y a surement un expert dans les parages
Mais ce qu'il faut retenir, il faut le strict minimum dans le traitement d'une interruption.
Une interruption par principe doit être super courte. Une impression peut être longue donc sur le principe ce n’est pas une bonne idée
De plus, Lors de l’exécution d’ une interruption vous êtes dans un contexte particulier où suivant les plateformes les interruptions sont suspendues. print dépend des interruptions et donc ca peut causer des soucis. Sur AVR arduino a mis du code special pour gérer cela mais ce nest pas le cas sur toutes les plateformes.
Dans votre cas particulier cependant le problème c’est sans doute que sur ESP vous devez avoir tout le code appelé par l’ISR avec l’attribut ICACHE_RAM_ATTR et en appelant ces fonctions externes dans l’ISR ce n’est plus le cas, d’où le crash.