Interruption, deep sleep et Serial

Bonsoir,
J’ai pour projet l’utilisation de ce type de compteur d’eau qui envoi une impulsion / litre consommé.

Mes premiers essais se font sur un arduino mais le but est de passer sur Attiny pour des raison de taille. Comme le dispositif fonctionnera sur pile et pour des raison d’optimisation je pars sur l’utilisation du deep-sleep.

Le code mini est le suivant :

#include <avr/sleep.h>
#include <avr/interrupt.h>
#define interruptPin 2

unsigned long pulses = 0;


// Reed switch interrupt
void countPulses()
{
  pulses++;
}

void setup()
{
  ADCSRA &= ~_BV(ADEN); // switch ADC OFF
  ACSR |= _BV(ACD);     // switch Analog Compartaror OFF
  Serial.begin(115200);
  pinMode(interruptPin, INPUT_PULLUP);
}

void system_sleep()
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();
  sleep_mode();
  sleep_disable();
}
// Main loop
void loop()
{
  attachInterrupt(digitalPinToInterrupt(interruptPin), countPulses, FALLING);
  Serial.print("Pulses :");
  Serial.println(pulses);

  Serial.println("Before syst sleep CALL");
  system_sleep();
  Serial.println("After syst sleep CALL");
}

Les questions maintenant :

  • lors de l’execution avec capteur reed le compteur se met à jour, mais seule une interruption sur 2 passe dans le serial (quelque soit l’intervalle) entre 2 interruptions. ( pulse est toujours pair, cf ci dessous)
  • l’utilisation de serial n’est pas envisagée à terme, mais par curiosité, pkoi des caractères étranges dans ce cas (vitesse verifiée et OK)
18:52:35.107 -> After syst sleep CALL
18:52:35.107 -> Pulses :64
18:52:35.107 -> Before syst sleep ⸮⸮115
18:52:42.079 -> After syst sleep CALL
18:52:42.079 -> Pulses :66
18:52:42.079 -> Before syst sleep ⸮⸮115
18:59:28.130 -> After syst sleep CALL
18:59:28.130 -> Pulses :68
18:59:28.130 -> Before syst sleep ⸮⸮115
18:59:34.958 -> After syst sleep CALL
18:59:34.958 -> Pulses :70
18:59:34.958 -> Before syst sleep ⸮⸮115
18:59:36.543 -> After syst sleep CALL
18:59:36.543 -> Pulses :72
18:59:36.543 -> Before syst sleep ⸮⸮115
18:59:41.686 -> After syst sleep CALL
18:59:41.686 -> Pulses :74
18:59:41.686 -> Before syst sleep ⸮⸮115
18:59:50.500 -> After syst sleep CALL
18:59:50.500 -> Pulses :76
18:59:50.500 -> Before syst sleep ⸮⸮115
19:00:02.133 -> After syst sleep CALL
19:00:02.133 -> Pulses :78
19:00:02.133 -> Before syst sleep ⸮

Merci

pulse devrait être volatile et quand vous l'utilisez hors de l'interruption ce devrait être en section critique

les caractères louches que vous voyez sont des scories liées au fait que vous demandez sauvagement de dormir alors que le port Série n'a pas tout envoyé sans doute

void loop()
{
  // SECTION CRITIQUE
  noInterrupts();
  unsigned long pulsesCopy = pulses;
  interrupts();

  Serial.print("Pulses :");
  Serial.println(pulsesCopy);
  Serial.println("Before syst sleep CALL");
  Serial.flush(); // on attend d'avoir tout envoyé

  system_sleep();

  Serial.println("After syst sleep CALL");
  Serial.flush(); // on attend d'avoir tout envoyé
}

pourquoi ne pas mettre ceci dans le setup()?  attachInterrupt(digitalPinToInterrupt(interruptPin), countPulses, FALLING);

Milles merci pour les explications et corrections.
J’ai apporté une correction ‘supplémentaire’ la suppression de sleep_mode() dans system_sleep(), ma variable est incrémenté et reporté via le Serial à chaque fois (reporté une fois sur deux précédemment).
Effectivemnent Serial.flush corrige l’affichage.

Pour l’appel à attachInterrupt dans la loop c’est une erreur :confused:.
D’ailleur je me suis librement inspiré de Gammon Forum : Electronics : Microprocessors : Interrupts et l’interruption est détaché puis réattaché dans la routine d’interruption, mais je ne comprends pas encore bien pourquoi…
Il va falloir encore un peu de travail :wink:
Merci

En détachant l’interruption dans l’interruption vous êtes sûr qu’elle ne se redéclenchera pas avant que vous ayez une chance de la traiter dans la loop