Gerer sequence de Bricoleau

Mon projet de répondeur arrive à son terme, toutefois je bloque sur une dernière mise au point, à savoir, utilisant la fonction gérer séquence de la librairie de Bricoleau, je n’arrive pas à contourner une partie ou raccourcir une étape en présence d’un évènement extérieur. Dans mon code, de 0 à 10 les étapes se succèdent jusqu’au terme du temps maximum d’enregistrement, et ça fonctionne parfaitement. En cas de coupure d’appel de l’appelant, je souhaite raccourcir l’enregistrement à l’essentiel, les 11000 ms allouées étant un maximum. Dans cette éventualité, il me faut soit intervenir au niveau étape 7 ou 8 , soit créer une fonction propre à un évènement extérieur, mettant fin à la séquence et prenant en charge les paramètres d’arrêt du système. C’est l’option que j’ai tenté de choisir, vainement.
y_a_t_il possibilité d’intervenir en cours de séquence et de la modifier en conséquence?
J’ai adjoint la partie concernée du code, l’intégralité étant conséquente.`

bool initial = false;         // variable fin d'appel
bool confirmation = false;    // variable confirmant vouloir mettre fin à la séquence
bool memorec1 = false;        // variable mémoire présence message 1 sur recorder
bool arret = false;           // variable pour arret séquence en absence de code reçu
bool enreg = false;           // variable autorisation enregistrement si code reçu


void gerersequence()           // Déclaration fonction séquence
{
  static byte etape = 0;
  static unsigned long chrono = 0;
  unsigned long delai = millis() - chrono;         // calcul durée de chaque étape
  if (etape == 0 && lancerSequence)
  {
    lancerSequence = false;
    digitalWrite(Religne, HIGH);               // relais ligne
    digitalWrite(Alan, HIGH);                  // Alim module annonce
    digitalWrite(PchangMute, HIGH);            // commutateurs reed niveau audio
    digitalWrite(Pchang200, HIGH);
    digitalWrite(Pchang100, HIGH);
    etape++;
    chrono = millis();
  }
  else if (etape == 1 && delai >= 3000)
  {
    pinMode(LectA, OUTPUT);                   // impulsion départ lecture annonce
    etape++;
    chrono = millis();
  }
  else if (etape == 2 && delai >= 500)
  {
    pinMode(LectA, INPUT);                    // fin impulsion lecture annonce
    etape++;
    chrono = millis();
  }
  else if (etape == 3 && delai >= 30000)          // fin de 1ère partie lecture annonce
  {
    digitalWrite(Refct, HIGH);                    // basculement relais fonction en réception
    etape++;
    chrono = millis();
  }
  else if (etape == 4 && delai >= 11000)
  {
    if (memoDTMF == false)    //  si code DTMF absent,variable arret bascule vraie pour la condition de coupure appel
    {
      arret = true;
    }
    else
      digitalWrite(Refct, LOW);             // relais fonction re bascule en émission
    etape++;
    chrono = millis();
  }
  else if ( etape == 5 && delai >= 6000)    // delai diffusion 2ème partie annonce
  {

    digitalWrite ( Alan, LOW);              // fin d'annonce, coupure alim module annonce
    enreg = true;
    etape++;
    chrono = millis();
  }
  else if (etape == 6 && delai >= 400)
  {
    arret = false;                // remise à zéro de la variable, le code ayant été reçu
    pinMode(Rec, OUTPUT);          // impulsion démarrage enregistrement
    etape++;
    chrono = millis();
  }
  else if (etape == 7 && delai >= 200)
  {
    pinMode(Rec, INPUT);              // fin impulsion démarrage enregistrement
    digitalWrite(Refct, HIGH);        // relais fonction re bascule en réception
    if (confirmation == true)      // condition d'activation fin enregistrement sur coupure ligne appelant
    { cloture();                    // fonction de cloture séquence anticipée
      lancerSequence = false;
      etape = 0;
    }
    etape++;
    chrono = millis();
  }
  else if (etape == 8 && delai >= 110000)    // délai maximum d'enregistrement message
  { pinMode (Rec, OUTPUT);                  // impulsion de fin enregistrement
    etape++;
    chrono = millis();
  }
  else if (etape == 9 && delai >= 500)
  {
    pinMode(Rec, INPUT);                     // fin d'impulsion fin enregistrement.
    etape++;
    chrono = millis();
  }
  else if (etape == 10 && delai >= 500)
  {
    digitalWrite(Arec1, LOW);               // paramètres de cloture en fin de séquence au terme du temps maximum imparti
    digitalWrite (Arec2, LOW);
    digitalWrite(Religne, LOW);
    digitalWrite(Refct, LOW);
    digitalWrite(PchangMute, LOW);
    digitalWrite(Pchang200, LOW);
    digitalWrite(Pchang100, LOW);
    memorec1 = true;
    enreg = false;
    memoDTMF = false;
    lancerSequence = false;
    etape = 0;

  }
  if (digitalRead(A1) == HIGH)memoDTMF = true;     // origine variable mémoire code reçu

  if (( memorec1 == false) && ( enreg == true))digitalWrite(Arec1, HIGH); // si pas de  mémoire M1, déclenche Alim recorder 1

  if (memorec1 == true)
    digitalWrite(13, HIGH);      // 5 volts pin 13 vient bloquer optocoupleur activation démarrage séquence


  if ( memorec1 == true)clignoter1();        // fonction clignotement led présence message



  if ((enreg = true) &&  (initial == true))
    confirmation = true;
  // variable confirmation(fin de séquence)vraie, si enregistrement activé lors de la coupure appel
  // confirmation active " void cloture " avec tous les paramètres de fin de séquence.
}


void setup {}


void loop {}


void cloture() {


  pinMode(Rec, OUTPUT);
  delay(500);
  pinMode(Rec, INPUT);
  delay(500);
  digitalWrite(Arec1, LOW);    // si enreg en cours + mémoire M1 fausse lors fin coupure appel, déclenche arrêt enreg = séquence clôture appel
  digitalWrite (Arec2, LOW);
  digitalWrite(Religne, LOW);
  digitalWrite(Refct, LOW);
  digitalWrite(Arec2, LOW);
  digitalWrite(Alan, LOW);
  digitalWrite(PchangMute, LOW);
  digitalWrite(Pchang200, LOW);
  digitalWrite(Pchang100, LOW);
  arret = false;
  enreg = false;
  initial = false;
  memoDTMF = false;
  memorec1 = true;
  confirmation = false;
  lancerSequence = false;
  etape = 0;
}

}

je précise fonctionner sur carte Nano atmel 328 V3 ch340 et qu’actuellement avec différents scénario de fin de séquence en présence coupure appel, j’ai toujours obtenu que l’enregistrement s’arrête bien lorsque la variable initial est vraie, mais les relais, le clignotement led présence message et les alimentations ne s’arrêtent qu’au terme de la séquence. En fait, les 110000ms s’écoulent invariablement avant la clôture séquence.

le code posté ne doit pas être le bon ou complet…

Mince j’ai carrément mon pseudo dans le titre du topic :sweat_smile:
Du coup je suis un peu dans l’obligation de répondre mais comme dit JML, il manque des bouts dans le code indiqué, même si effectivement j’y reconnais ma touche.

le code complet est vaste, avec la gestion télécommande, DTMF et coupure appel. j’ai volontairement repris la seule partie qui me semble concernée. C’est vrai que gerer sequence comprend sa partie commande, ici non reportée. Afin d’être plus clair, je vais m’attacher à reprendre mon code avec un exemple plus simplifié d’allumage led, le tester sur une autre nano, en reprenant les mêmes principes de codage. Cela me confirmera si je me suis bien planté, et je vous remettrai l’intégralité du code afin de ne rien omettre. Merci à vous deux en attendant.

voici le code test avec leds, reprenant le même esprit.
Il compile, mais pas encore testé. Je tenterai demain de faire des essais.

#include <simpleBouton.h>


simpleBouton bouton(2);
unsigned long tempoDepart = 0;
int tempoActive = 0;
bool lancerSequence = false;
const int ledRouge = 3;
const int ledOrange = 4;
const int ledJaune = 5;
const int ledIndigo = 6;
const int ledBlanche = 7;
const int ledBleu = 8;
const int ledVerte = 9;
const int ledRouge2 = 10;
const int ledBuiltin = 13;
const int SW = 11;
const int ledVerte2 = 12;

bool validation = false;
bool arret = false;
bool memoCode = false;
bool anomalie =  false;
bool cloture = false;
bool memoFin = false;

void gerersequence()
{
  static byte etape = 0;
  static unsigned long chrono = 0;
  unsigned long delai = millis() - chrono;
  if (etape == 0 && lancerSequence)
  { lancerSequence = false;

    digitalWrite (ledRouge, HIGH);
    digitalWrite(ledOrange, HIGH);
    digitalWrite(ledIndigo, HIGH);

    etape++;
    chrono = millis();
  }
  else if (etape == 1 && delai >= 3000)
  { digitalWrite(ledVerte, HIGH);
    etape++;
    chrono = millis();
  }
  else if (etape == 2 && delai >= 500)
  { digitalWrite(ledVerte, LOW);
    etape++;
    chrono = millis();
  }
  else if (etape == 3 && delai >= 30000)
  { digitalWrite(ledBleu, HIGH);
    etape++;
    chrono = millis();
  }
  else if (etape == 4 && delai >= 11000)
  { digitalWrite(ledBleu, LOW);
    if (memoCode == false)    //  si code absent,variable arret bascule vraie pour la condition de coupure
    {
      arret = true;
      etape++;
      chrono = millis();
    }
    else if ( etape == 5 && delai >= 6000)
    { digitalWrite(ledRouge, LOW);
      validation = true;
      etape++;
      chrono = millis();
    }
    else if (etape == 6 && delai >= 400)
    { digitalWrite(ledBlanche, HIGH);
      digitalWrite(ledVerte2, HIGH);
      arret = false;
      etape++;
      chrono = millis();
    }
    else if (etape == 7 && delai >= 200)
    { digitalWrite(ledBlanche, LOW);
      etape++;
      chrono = millis();
    }
    else if (etape == 8 && delai >= 110000)
    { digitalWrite(ledBlanche, HIGH);
      etape++;
      chrono = millis();
    }
    else if (etape == 9 && delai >= 500)
    { digitalWrite(ledBlanche, LOW);
      etape++;
      chrono = millis();
    }
    else if (etape == 10 && delai >= 500)
    { digitalWrite(ledBleu, LOW);
      digitalWrite(ledJaune, LOW);
      digitalWrite(ledOrange, LOW);
      digitalWrite(ledIndigo, LOW);
      memoFin = true;
      lancerSequence = false;
      etape = 0;

    }
    if ((arret == true) && (validation == true))
      anomalie = true;

    if (memoFin = true)digitalWrite(ledRouge2, HIGH);

    if (anomalie = true)digitalWrite(ledBuiltin, HIGH); // signalement code non reçu
    //fonctionnement vérifié en déclarant arret true en début de code.

    if (digitalRead(11) == LOW)cloture = true;     // appui bouton à partir de l'étape 5(simulation coupure)

    if ((cloture == true) && ( validation == true))   // condition pour réaliser les étapes 8,9 et 10
    {                    }       // sans attendre le terme des 110000ms entamée entre 7 et 8.
    // Entre parenthèses,endroit présumé pour écrire le code adhéquat ayant pensé
    // créer une fonction void cloture intégrant les commandes des etapes 8,9 et 10, s'affranchissant
    // du solde des 110000ms entamées.




  }
}
void gererBouton()
{ static bool repos = true;
  bouton.actualiser();
  if (repos && bouton.estEnfonceDepuisAuMoins(3000))

    lancerSequence = true;
  else
    lancerSequence = false;
}



void setup() {
  pinMode(ledRouge, OUTPUT);
  pinMode(ledOrange, OUTPUT);
  pinMode(ledJaune, OUTPUT);
  pinMode(ledBlanche, OUTPUT);
  pinMode(ledVerte, OUTPUT);
  pinMode(ledBleu, OUTPUT);
  pinMode(ledIndigo, OUTPUT);
  pinMode(ledBuiltin, OUTPUT);
  pinMode(ledRouge2, OUTPUT);
  pinMode(SW, INPUT_PULLUP);
  pinMode(ledVerte2, OUTPUT);


}

void loop() {
  for (int count = 0; count < 1; count++)
    gererBouton();
  gerersequence();


}

dans cette fonction repos est toujours vrai

void gererBouton()
{ static bool repos = true;
bouton.actualiser();
if (repos && bouton.estEnfonceDepuisAuMoins(3000))

  lancerSequence = true;
else
  lancerSequence = false;
}

autant écrire

void gererBouton() { 
  bouton.actualiser();
  lancerSequence =  bouton.estEnfonceDepuisAuMoins(3000);
}

sinon je pense qu’il faut redessiner la machine à état, pour comprendre où vous devez tenir compte de la présence d’un évènement extérieur et toutes ces manipulations sur les LEDs et les états pourraient sans doute être bcp plus compact en mettant tout dans une qui décrit l’état des LEDs (ou les transitions) car globalement vous faites toujours la même chose: allumez et éteindre des LEDs au bout d’un certain temps et passer à l’étape suivante

Mon exemple avec leds vous a plutôt éloigné , car à priori peu concret. J’ai donc persévéré, et chercher dans une autre direction, laquelle a porté ses fruits. Premièrement, mon évènement extérieur, signal coupure appel avait un niveau trop bas pour être pris en compte. C’est en analysant signaux par signaux progressivement au cours de l’évolution de la séquence, que j’en ai fait le constat. Deuxièmement, mon scénario de clôture était mal organisé, le relais de commutation entrée/sortie ligne devant être désactivé en dernier, sinon je n’obtenais pas le compte des 5 tonalités mettant fin à ma séquence enregistrement.Désormais , tout fonctionne comme souhaité et donc je peux répondre moi-même à ma question du premier post. Oui, il y a possibilité d’intervenir en cours de séquence, de l’interrompre à tout moment ou en modifier le cours. Merci en tout cas pour vos interventions et désolé pour Bricoleau de l’avoir contraint à intervenir en le citant. :wink:

bravo !

Aucun souci
Ta démarche est nickel : réfléchir, analyser pas à pas jusqu’à comprendre, pour finalement mettre au point le programme qui répond au besoin.