J'ai un capteur réalisé à l'aide d'un pro mini que je mets en LowPower pour 24 heures en faisant une boucle avec les incréments max de 8 secondes. Au bout de ces 24 heures, il se réveille et me dit s'il est vivant (mesure de la tension de la pile), puis se ré-endort.
Entre temps, si mon capteur reçoit une information qui m'intéresse, je le réveille par une interruption matérielle.
Tout ça fonctionne mais je souhaite placer dans la procédure d'interruption un système anti-rebond basé sur le comptage du temps.
C'est là que ça se gâte : apparemment, puisque je suis en LowPower, il semble que la fonction "millis()" ne s'incrémente pas. De ce fait, mon test anti-rebond ne fonctionne pas :
void loop() {
for (int i = 0; i < 10800; i++) { // 24 heures de sommeil
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
float VCC = readVcc();
dtostrf(VCC, 3, 2, str);
Serial.print("Tension pile = "); // Pour test
Serial.println(str); // Pour test
delay(100); // Laisser le temps à "Serial" de s'exécuter avant de retourner en "Power Down"
}
float readVcc() { // Lecture de la tension de la pile
return K_BATT * analogRead(V_BATT);
}
void onEvent() {
T2 = millis();
if (T2 - AntiRebond > 200) {
Serial.println(T2);
AntiRebond = T2;
if(digitalRead(pinInterrutp) == LOW) {
Serial.println("Vers le bas ");
} else {
Serial.println("Vers le haut ");
}
delay(100); // Laisser le temps à "Serial" de s'exécuter avant de retourner en "Power Down"
}
}
Une solution serait de stopper la mise en veille lors de l'interruption matérielle, mais je n'ai pas trouvé de fonction qui fasse cela.
incrémenter un compteur à chaque interruption de 8s.
vérifier que le compteur a changé lorsqu'une interruption matérielle arrive
Si le temps entre 2 interruptions matérielles devait être inférieur à 8s il faudrait peut-être augmenter la fréquence du réveil.
Il y a probablement d'autres solutions.
Effectivement, n'attendant pas d'évènement à une récurrence supérieure à 8 secondes, le fait de remplacer "millis()" par un compteur incrémenté toutes les 8 secondes fonctionne parfaitement. Le code est alors le suivant :
void loop() { for (int i = 0; i < 10800; i++) { // 24 heures de sommeil
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
cmpt = i;
}
float VCC = readVcc();
dtostrf(VCC, 3, 2, str);
Serial.print("Tension pile = "); // Pour test
Serial.println(str); // Pour test
delay(100); // Laisser le temps à "Serial" de s'exécuter avant de retourner en "Power Down"
}
float readVcc() { // Lecture de la tension de la pile
return K_BATT * analogRead(V_BATT);
}
void onEvent() {
if (cmpt - AntiRebond > 0) {
Serial.println(cmpt);
AntiRebond = cmpt;
if(digitalRead(pinInterrutp) == LOW) {
Serial.println("Vers le bas ");
} else {
Serial.println("Vers le haut ");
}
delay(100); // Laisser le temps à "Serial" de s'exécuter avant de retourner en "Power Down"
}
}
Merci à tous pour vos différentes idées et solutions.
Juste après avoir répondu hier, j'ai pensé au bouclage, lorsque mon compteur repassait à zéro. C'est un problème classique de débordement. Pour y pallier, je réinitialise ma variable :
AntiRebond = -1;
à chaque repassage au début de la "loop()". Ça fonctionne très bien.
Non, je viens de tester, chaque interruption est prise en compte.
Par contre, un effet de bord que j'avais noté et qui apparaît clairement est qu'au retour de chaque interruption matérielle, le système ne revient pas dans son cycle courant de "LowPower", mais passe au suivant (la boucle est incrémentée).
Ça ne me gêne pas, mais est-ce inhérent au système ou dû à ma programmation ?