conseil pour temporisation bouton par millis

Bonjour,

Afin de valoriser au mieux le temps désormais disponible de ma retraite, ancien technicien TV, je viens récemment de m'initier au langage Arduino.
je bloque sur le script d'un programme partiel fonctionnant bien à la première impulsion sur le bouton, mais différemment sur les suivantes, ce qui ne me convient pas.
La carte est une Nano Atmega 328.
Le but étant que la led s'allume au bout de 5 secondes d'appui sur le bouton, sans coupure.
Si relâchement en cours d'appui, alors recomptage à partir de zéro.
L'application future étant sur réseau téléphone, les impulsions parasites ne seront pas prises en compte.
Le téléversement et la carte fonctionne à merveille, sauf que seul le premier appui est concluant, les suivants allument instantanément la led. Seul le reset de la carte ré-autorise l'accès à la première temporisation suivante de 5 secondes et ainsi de suite.
j'ai pensé à un problème de boucle ou de mémo millis précédent ou encore un reset millis.
Non expert, je m'en réfère à vos conseils avisés.
j'ai tenté mille essais différents glanés sur internet, en vain.
Merci d'avance à celui ou ceux qui accepteront s'y intéresser.
Pierre.

const byte bouton = 2;                 
const byte led = 13;
const unsigned long duree = 5000ul;
unsigned long chrono = 0;
bool enfonce = false;
bool etatPrecedent = HIGH;

void setup()  {
  
  pinMode(bouton,INPUT_PULLUP);      // bouton entrée digitale D2
  pinMode(led,OUTPUT);               // led carte Nano 
  pinMode(5,INPUT);                  // entrée en pull Down activée par la sortie D 13
  pinMode(10,OUTPUT);                // led activée en fin de temporisation bouton
  pinMode(6,OUTPUT);                 // seconde sortie potentielle, ici non utilisée.
}

  void loop()  {
   
    
  
  bool etatBouton = digitalRead (bouton);
  if (!etatBouton)  {  // bouton enfoncé         // condition départ chrono
    enfonce = true;
   
     
    

    if ( etatPrecedent)  chrono = millis(); // on lance le chrono
    
    if ( millis() - chrono > duree && enfonce)digitalWrite(13,HIGH);        // condition duréee impulsion

    if(digitalRead(5) == HIGH) {                   // Entrée D5 activée par D13 ( sans cette connexion,la tempo ne fonctionne pas!)  
      digitalWrite(10,HIGH);                       // la led en D10 s'allume
      delay(3000);                                 // temporisation 3 secondes 
      digitalWrite(10,LOW);                        // la led en  D10 s'éteind
    }
    
        
    enfonce = false;
  }
    etatPrecedent = etatBouton ;
    
   
  
}

Ton problème peut venir d'ici :

    if(digitalRead(5) == HIGH) {                   // Entrée D5 activée par D13 (sans cette connexion, la tempo ne fonctionne pas!) 
      digitalWrite(10,HIGH);                       // la led en D10 s'allume
      delay(3000);                                 // temporisation 3 secondes
      digitalWrite(10,LOW);                        // la led en  D10 s'éteind
    }

Le delay doit f** la m**...

J'ai nettoyé ton code et ajouté un petit delay pour annuler les rebonds du bouton.
Essaye déjà comme ça, avant d'ajouter les lignes avec le delay

const byte bouton = 2;                 
const byte led = 13;
const unsigned long duree = 5000ul;
unsigned long chrono = 0;
bool etatPrecedent = HIGH;

void setup()  {
  pinMode(bouton,INPUT_PULLUP);      // bouton entrée digitale D2
  pinMode(led,OUTPUT);               // led carte Nano
  pinMode(5,INPUT);                  // entrée en pull Down activée par la sortie D 13
  pinMode(10,OUTPUT);                // led activée en fin de temporisation bouton
  pinMode(6,OUTPUT);                 // seconde sortie potentielle, ici non utilisée.
}

void loop()  {
  bool etatBouton = digitalRead (bouton);
  if (!etatBouton)  {  // bouton enfoncé         // condition départ chrono

    if (etatPrecedent)  { // on vient d'enfoncerle bouton
    	chrono = millis(); // on lance le chrono
    	delay(30);  // debounce button
    }
   
    if (millis() - chrono > duree) digitalWrite(13,HIGH);  // condition duréee impulsion

/*    if(digitalRead(5) == HIGH) {                   // Entrée D5 activée par D13 (sans cette connexion, la tempo ne fonctionne pas!) 
      digitalWrite(10,HIGH);                       // la led en D10 s'allume
      delay(3000);                                 // temporisation 3 secondes
      digitalWrite(10,LOW);                        // la led en  D10 s'éteind
    }*/
  }
  etatPrecedent = etatBouton ;
}

Ce delay devra être remplacé lui aussi par un second chrono

Merci Lesept pour ta réactivité surprenante!
Et pour ton efficacité aussi.
Effectivement, ta version de code fonctionne très bien tel que tu l'as figé à l'essentiel, à savoir juste s'occuper de la commande de led en D13.
çà se complique dès que je rajoute d'autres commandes sorties supplémentaires, je reviens tout de suite à mon problème initial.
Rassures-toi, j'ai trouvé la cause ainsi qu'une première solution, qui certainement selon toi, relèvera du bricolage!
Il faut que ma boucle s'auto-maintienne tant que les fonctions voulues s'exécutent, et qu'en fin de cycle j'opère une rupture.
j'ai fait un test concluant avec un script cours.
Dès demain, je reviens le transcrire ici afin que tu puisses mieux me comprendre.

Il faut envisager tes autres fonctions de la même manière que ce que tu as écrit pour ton bouton.

Si tout est réglé par des durées, il existe des bibliothèques qui gèrent ça très bien

merci pour le retour.
Effectivement, la suite n'est qu'une succession de durées et de commutations telles que dans l'exemple suivant.
Le problème des bibliothèques est que je ne les ai trouvées qu'en anglais et pas forcément celles souhaitées.
As-tu une recommandation à ce propos? Étant novice, je m'y perd quelque peu!

Le bouton faisait office d'exemple, dans la réalité c'est un optocoupleur qui gèrera la commande.
(isolation de la ligne téléphonique véhiculant 80 volts alternatifs en mode sonnerie, pas vraiment recommandés pour la Nano)
Idem en sortie pour certaines commandes périphériques et respect des courants de charge.

Ma façon de couper la boucle n'est pas très catholique( digitalWrite(7,LOW) , toutefois ça fonctionne.
j'ai tenté avec un break, sans succès, certainement mal utilisé ou mal placé.

il me reste à peaufiner mon script selon ton éventuel retour conseil. J'édite toutefois ci-après celui qui résout ma problématique initiale pour l'instant. ça pourrait servir à d'autres, sans prétention aucune, c'est l'un des buts de ce forum après tout.

const byte bouton = 2;                 
const byte led = 13;
const unsigned long duree = 5000ul;
unsigned long chrono = 0;
bool etatPrecedent = HIGH;

void setup()  {
  pinMode(bouton,INPUT_PULLUP);      // bouton entrée digitale D2
  pinMode(led,OUTPUT);               // led carte Nano
  pinMode(5,INPUT);                  // entrée en pull Down activée par la sortie D 13
  pinMode(10,OUTPUT);                // led activée en fin de temporisation bouton
  pinMode(6,OUTPUT);                // seconde sortie potentielle, ici non utilisée.
  pinMode(4,OUTPUT);
  pinMode(7,OUTPUT);
}

void loop()  {
  bool etatBouton = digitalRead (bouton);
  if (!etatBouton)  {  // bouton enfoncé        // condition départ chrono

    if (etatPrecedent)  {                             // on vient d'enfoncer le bouton
      chrono = millis();                                // on lance le chrono
      delay(30);                                        // debounce button
    }
   
    if (millis() - chrono > duree) digitalWrite(13,HIGH);     //si condition duréee impulsion vraie, D13 
                                                                               passe à1                                                                          

    if (digitalRead(5)==HIGH)          //  sortie D13 reliée à Entrée D5(pull down), si la condition est vraie,
                                                    ouverture boucle travail suivante
     
    {
      
     digitalWrite(7,HIGH);       /*  sortie D7 reliée à entrée D5 (en parallèle de D13), assurant la 
                                       continuité de la boucle de travail et remettant à zéro
                                       la condition de temporisation appui bouton lors du basculement de D13 à 0
                                        */
                                       
     delay(100);                       // délai de sécurité de commutation 
     digitalWrite(13,LOW);          // remise à zéro de la condition temporisation appui bouton 5
                                            secondes permettant de recréer à l'infini la condition 
     
     digitalWrite (6,HIGH);            // déroulement de la suite travail (exemple) 
     digitalWrite(4,HIGH);             //              ''
     delay(2000);                       //              ''     
     digitalWrite(4,LOW);             //              ''  
     delay(2000);                       //              ''
     digitalWrite(4,HIGH),             //              ''
     delay(2000);                       //              ''  
     digitalWrite(4,LOW);             //              ''
     digitalWrite(6,LOW);             //              ''
       
     digitalWrite(7,LOW);              // permet de finaliser de la boucle travail en annulant la condition if 
                                                 digitalRead 5=1 (rupture de boucle)   
   
     
    }
    
  }
  etatPrecedent = etatBouton ;
}

Je pense que Bricoleau a écrit des bibliothèques qui pourraient te servir. Elles gèrent les boutons et permettent de gérer des tâches.

Et elles sont en français, avec un support sur le forum...

Hello

Il y a plus simple que relier deux pins pour avoir un effet mémoire entre un digitalWrite et un digitalRead. Il suffit d'utiliser des variables.

lesept:
Je pense que Bricoleau a écrit des bibliothèques qui pourraient te servir. Elles gèrent les boutons et permettent de gérer des tâches.

Et elles sont en français, avec un support sur le forum...

Ouaip mais j'en ai une autre en préparation, qui va envoyer du bois :slight_smile:
Un véritable couteau suisse pour tout faire "en même temps"
Sortie dans quelques jours....

D'ici là, deux exemples pour répondre à ton problème :

Pour lancer une action après 5 secondes d'appui prolongé sur un bouton poussoir

#include "simpleBouton.h"

simpleBouton bouton(2); //cablage : 2----BP----GND

void action()
{
  Serial.println("action");
  //ou n'importe quoi d'autre
}

void gererBouton()
{
  static bool repos = true;
  
  bouton.actualiser();

  if (repos && bouton.estEnfonceDepuisAuMoins(5000))
  {
    action();
    repos = false;
  }
  
  if (bouton.vientDEtreRelache())
  {
    repos = true;
  }
}

void setup()
{
  Serial.begin(115200);
  //(simpleBouton s'occupe du pinMode et du debounce)
  ...
}

void loop()
{
  gererBouton();
  ...
}

Pour exécuter une séquence d'instructions avec des ruptures temporelles

bool lancerSequence = false;

void gererSequence()
{
 static byte etape = 0;
 static unsigned long chrono = 0;
 unsigned long delai = millis() - chrono;
 
 if (etape == 0 && lancerSequence)
 {
   Serial.println(F("Debut sequence"));
   lancerSequence = false;
   digitalWrite (6,HIGH);
   digitalWrite(4,HIGH);
   etape++;
   chrono = millis();
 }
 else if (etape == 1 && delai >= 2000) 
 {
   digitalWrite(4,LOW);
   etape++;
   chrono = millis();
 }
 else if (etape == 2 && delai >= 2000) 
 {
   digitalWrite(4,HIGH);
   etape++;
   chrono = millis();
 }
 else if (etape == 3 && delai >= 2000) 
 {
   digitalWrite(4,LOW);
   digitalWrite(6,LOW);
   etape = 0;
   Serial.println(F("Fin sequence"));
 }
}

... il ne reste plus qu'à mettre ailleurs dans le code : lancerSequence = true;

void loop()
{
 ...
 gererSequence();
}

Je te laisse ajuster et coller les deux morceaux

a+

bricoleau:
Ouaip mais j'en ai une autre en préparation, qui va envoyer du bois :slight_smile:
Un véritable couteau suisse pour tout faire "en même temps"
Sortie dans quelques jours....

J'ai hâte de voir ça...

Merci à vous deux, Lesept et Bricoleau.

J'ai travaillé sur mon projet ce dimanche en respectant le conseil d'utiliser principalement millis dans mes fonctions chrono.
Entre temps vous m'avez apporté de nouvelles pistes que je m'efforcerai d'appliquer le plus rapidement. En reprenant mon travail, j'apprendrai davantage.
Cependant, je ne comprend pas pourquoi mon dernier script où 2 boucles chrono se succèdent, c'est seulement la première qui fonctionne.
Écrites l'une sans l'autre,chacune est opérationnelle, ensemble ça coince.
Ce script édité ci-après s'approche davantage de mon projet réel.

Bien entendu, ce script a été composé juste avant lecture de vos dernières recommandations.

a+

const byte bouton = 2;                 
const byte led = 13;
const unsigned long duree = 5000ul;
unsigned long chrono = 0;
bool etatPrecedent = HIGH;
const byte Sw =3;
const byte voy = 12; 
int tempoActive = 0;
unsigned long tempoDepart= 0;
void setup()  {
  pinMode(bouton,INPUT_PULLUP);      // entrée optocoupleur 1, temporisation
  pinMode(led,OUTPUT);               // led carte Nano
  pinMode(5,INPUT);                  // entrée en pull Down activée par la sortie D 13
  pinMode(10,OUTPUT);                // led activée en fin de temporisation entrée
                                                  optocoupleur 1
  pinMode(6,OUTPUT);                 // sortie
  pinMode(4,OUTPUT);                 // sortie  
  
  pinMode(8,OUTPUT);                 // sortie
  pinMode(Sw,INPUT_PULLUP);        // entree Optocoupleur 2, temporisation
  pinMode(voy,OUTPUT);               // led et sortie activée en cours de temporisation
                                                 activée par optocoupleur 2
   
}
 
void loop()  {

  if(digitalRead(Sw) ==LOW)digitalWrite(voy,HIGH);  // si optocoupleur =1 , commande
                                                                       et voyantlecture validés

if(digitalRead(Sw)==LOW) {
  tempoActive = 1;
  tempoDepart = millis();
}
if(tempoActive)
if((millis()-tempoDepart)>=10000){                  // temporisation module lecture 
                                                                    message de 10 secondes

  digitalWrite(voy,LOW);
  tempoActive=0;
       
  
 
    
    bool etatBouton = digitalRead (bouton);
  if (!etatBouton)  {  // bouton enfoncé         // condition départ chrono

    if (etatPrecedent)  { // on vient d'enfoncer le bouton
     chrono = millis(); // on lance le chrono
      delay(30);  // debounce button
    }   
    if (millis() - chrono > duree) digitalWrite(13,HIGH);  //si condition durée impulsion
                                                                          vraie, D13 passe à 1

    else  {
      digitalWrite(13,LOW);   }                        // si durée non atteinte rester à l'état
                                                                   bas    

    if (digitalRead(5)==HIGH)                    // 13 étant bouclé sur l'entrée 5, la 
                                                             condition est validée pour entrer                 
                                                             dans la boucle de travail suivante
    {      
                                     
     digitalWrite(10,HIGH);                    // suite de fonctions diverses de la boucle 
                                                         travail
     digitalWrite( 8,HIGH);                    //             "
     delay(10000);                              //             "
     digitalWrite(10,LOW);                    //             " 
     digitalWrite(8,LOW);                      //             "
     
     
     
     
    
    }    
  }  etatPrecedent = etatBouton ;

        

}
}

Ton code est complexe, mais si tu veux chronométrer deux choses différentes, il te faut deux chronos. Donc deux variables différentes

Le problème de blocage entre mes deux chrono est résolu grâce à la bibliothèque de Bricoleau. De plus ça m'a permis d'apprendre à l'utiliser, c'est génial et super pratique.
J'ai hâte de découvrir sa prochaine mouture. Encore merci à vous deux.
Prochaine étape, comprendre l'utilisation de variables pour remplacer:

" Il y a plus simple que relier deux pins pour avoir un effet mémoire entre un digitalWrite et un digitalRead. Il suffit d'utiliser des variables. "

Pour l'heure, je suis à la traîne en la matière.
J'avoue que même si ma bidouille fonctionne, ce serait plus logique de pousser le script à son dernier retranchement.

Vous pouvez m'en dire davantage à ce propos?

Disons que l'approche qui consiste à relier des pins entre elles, me semble trahir des habitudes de "cableur" :slight_smile:

Sur un arduino, c'est dangereux car une incohérence de code pourrait faire comme un court circuit et tirer fortement sur l'alim.

Utiliser un digitalWrite pour fixer une sortie, puis la relire plus tard par un digitalRead sur une autre pin reliée, est quand même un peu hérétique.
Cela revient exactement au même qu'utiliser une simple variable globale de type booléen.

Essaye plutôt de t'approprier le code que j'ai mis plus haut. Le comprendre te fera progresser dans le monde arduino.

Conseils forts judicieux!
Dès application, tout est d'équerre. Merci encore.

Suppression de mon strap d'électricien!

Parfait fonctionnement des deux temporisations même en simultané.

Si la suite travail est saisie en "delay", les temporisations fonctionnent également, mais pas en même temps, ce qui peut être pratique dans certaines applications.

Problématique donc résolue sur tous les points.
Ce qui ne m'empêchera pas de revenir consulter fréquemment ce forum, où une foule d'informations intéressantes se renouvelle sans cesse.
Peut-être à bientôt, d'autres projets se profilent à l'horizon,dont la restauration et animation d'un réseau de train électrique. Ou encore, tenter une approche du monde arduino avec mes petits enfants en partageant avec eux les plaisirs de la découverte. Ne doutant pas que si intéressés, ils me dépasseront vite, ce que je leur souhaite vivement.

Merci Bricoleau et Lesept pour votre aimable et sympathique collaboration.

voici le script final et fonctionnel:

simpleBouton bouton(2); //cablage : 2----BP----GND
const int Sw = 3;                   
const int Lect = 12;                                   
int tempoActive =0;                    
unsigned long tempoDepart = 0;            
bool lancerSequence = false;

void gererSequence()
{
 static byte etape = 0;
 static unsigned long chrono = 0;
 unsigned long delai = millis() - chrono;
 
 if (etape == 0 && lancerSequence)
 {
  lancerSequence = false;
digitalWrite(10,HIGH);
digitalWrite(6,HIGH);
   etape++;
   chrono = millis();
   }  
  
 else if (etape == 1 && delai >= 1000)
 {
   digitalWrite(4,HIGH);
   etape++;
   chrono = millis();
 }
 else if (etape == 2 && delai >= 500)
 {
   digitalWrite(4,LOW);
   etape++;
   chrono = millis();
 }
 else if (etape == 3 && delai >= 500)
 {
   digitalWrite(4,HIGH); 
   etape++;
   chrono = millis();
 }
 else if (etape == 4 && delai>= 500)
 {
  digitalWrite(4,LOW);  
  etape++;
  chrono = millis();
 }
 else if (etape == 5&&delai>= 1000)
 
 {
  digitalWrite (10,LOW);
  
  etape++;
  chrono = millis();
 }
 else if (etape == 6 && delai >= 3000)

 {
 digitalWrite(6,LOW);
 digitalWrite (7,HIGH);
   
 
   etape = 0; 

  }
}
  
void gererBouton()
{
  static bool repos = true;
 
  bouton.actualiser();

  if (repos && bouton.estEnfonceDepuisAuMoins(5000))
  lancerSequence=true; 
  {
    
}
}
void setup(){
  pinMode(bouton,INPUT);
  pinMode(10,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(6,OUTPUT);  
  pinMode(Sw,INPUT_PULLUP);           
  pinMode(Lect,OUTPUT);                 
}

void loop(){ 

  gererBouton();

   gererSequence();

  
   if(digitalRead(Sw) ==LOW)digitalWrite(Lect,HIGH);  // si bouton Lecture enfoncé,déclenche alim modules recorder et ampli BF

if(digitalRead(Sw)==LOW) {
  tempoActive = 1;
  tempoDepart = millis();
}
if(tempoActive)
if((millis()-tempoDepart)>=10000){
  digitalWrite(Lect,LOW);
  tempoActive=0; 

}
}

Me revoici avec le script en question, version telle que définitive sur mon montage.
Alors que la simulation avec leds se passait fort bien, j’ai un rebond de la boucle activée par “le bouton” en entrée pin D2, en fait un optocoupleur fermé au moins 5 secondes pour déclencher la boucle.
La boucle fonctionne bel et bien, sauf qu’elle se fait en double, elle recommence une seconde fois, ce qui ne me faut pas! Alors qu’aux essais avec leds, pas d’anomalie constatée.
Le delay supprimé n’y fait rien, la seconde boucle tempo 15 minutes fonctionne bien.
j’ai beau ressaisir le script, chercher l’erreur… peut-être la trop longue liste à gérer pose problème ?

#include "simpleBouton.h"

simpleBouton bouton(2); //cablage : 2----BP----GND
const int Sw = 3;                   // pin 3 affectée à la constante bouton Lecture  
const int Lect = 12;                    // pin 12 affectée à la constante sortie Lecture                 
int tempoActive =0;                     // etat d'activation de la temporisation
unsigned long tempoDepart = 0;           // temps au point de départ chrono  
bool lancerSequence = false;

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

digitalWrite(6,LOW);                                  // assure ré-initialisation B au départ de la boucle 
digitalWrite(10,HIGH);                                // active C
delay(1000);
digitalWrite(6,HIGH);                                 // active B
digitalWrite(7,HIGH);                               // active R
etape++;
chrono=millis();
 }
 else if ( etape ==1 && delai >= 2000)
 {
  digitalWrite (4,HIGH);                               // active D  
  digitalWrite(8,HIGH);                                // active E
  etape++;
  chrono = millis();
 }
 else if (etape == 2 && delai >= 1000)
 {
  digitalWrite (4,LOW);                               // désactive D                             
  digitalWrite (8,LOW);                               // désactive E
  etape++;
  chrono= millis();
 }
 else if ( etape == 3 && delai >= 1000)
 {
 digitalWrite(4,HIGH);                                // ré- active D
 etape++;
 chrono= millis();
 }
 else if(etape ==4 && delai>= 1000)
 {
  digitalWrite (4,LOW);                              // désactive D
  etape++;
  chrono=millis();
 }
 else if (etape == 5 && delai>= 18000)              // tempo 1
 {
  digitalWrite (4,HIGH);                             // ré-active D
  etape++;
  chrono=millis();
 }
 else if (etape == 6 && delai>= 3000)                // tempo validation fonction longue de D
  
 {
  digitalWrite(10,LOW);                              // désactive C
  digitalWrite(4,LOW);                               // désactive D
  etape++;
  chrono=millis();
 }
 else if (etape == 7 && delai>= 90000)              // tempo 2
 {
  digitalWrite (4,HIGH);                            // ré-active D
  etape++;
  chrono=millis();
 }
 else if (etape == 8 && delai >= 1000)
 {
  digitalWrite(4,LOW);                            // désactive D  
  etape++;
  chrono=millis();
   }
   else if (etape == 9 && delai >= 5000)           // tempo validation 
 {
  digitalWrite (7,LOW);                // désactive R
  digitalWrite (6,HIGH);              // maintien Alim et afficheur module B allumé  témoin activité
  digitalWrite( 8,LOW);               // désactive E  
  digitalWrite(4,LOW);                // désactive D
  digitalWrite(10,LOW);              // dasactive C
  digitalWrite(Lect,LOW);            // assure que la fonction est bien au repos
 
 
  
   

   etape = 0; 

  


 
  }

  

}
void gererBouton()


{  static bool repos = true;
 
  bouton.actualiser();

  if (repos && bouton.estEnfonceDepuisAuMoins(5000))
  lancerSequence=true; 
  {
    
}
}

void setup(){
  pinMode(bouton,INPUT);
  pinMode(10,OUTPUT); 
  pinMode(4,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(Sw,INPUT_PULLUP);         // détermine 3 en entrée ( bouton temporisation lecture actif durant 15 minutes )  
  pinMode(Lect,OUTPUT);                 // détermine 12 en activation alimentation module A
}

void loop(){ 

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

   gererSequence();

  
   if(digitalRead(Sw) ==LOW)digitalWrite(Lect,HIGH);  // si bouton Lecture enfoncé,déclenche alim module A
   if(digitalRead(Sw) == LOW) digitalWrite(6,HIGH);                    "                                 B

if(digitalRead(Sw)==LOW) {
  tempoActive = 1;
  tempoDepart = millis();
}
if(tempoActive)
if((millis()-tempoDepart)>=900000){
  digitalWrite(Lect,LOW);
  tempoActive=0; 

}
}
}

un dernier essai avant d'aller dormir et constat qu'en remplaçant toute la chaîne "séquence" millis par l'usage de quelques delay, ma suite de fonctions refonctionne correctement sur une seule boucle, qui s'arrête bien en fin de séquence.( et non se reproduit une 2 eme fois, s'arrêtant ensuite)
j'en déduis une perturbation en utilisant millis uniquement sur l'ensemble du script édité dans mon précédent post.
j'aimerais comprendre.... d'autant que millis améliore la performance le plus souvent.

Dernier retour sur ce code, où une petite erreur faisait se reboucler les fonctions comprises à l’intérieur d’une des temporisation.

L’exemple donnait en partie:

 }
 else if (etape == 3 && delai >= 2000)
 {
   digitalWrite(4,LOW);
   digitalWrite(6,LOW);
   etape = 0;
   Serial.println(F("Fin sequence"));
 }

après maints essais, il fallait remplacer etape = 0; par etape == 0;

Comme quoi une erreur anodine se glisse facilement sans trop s’en apercevoir, d’autant pour le débutant que je suis. Encore une fois, ça aide à comprendre ce que l’on fait.

Merci à Bricoleau et Lesept pour leur aide à résoudre ce code.

Code complet corrigé :

#include <simpleBouton.h>


simpleBouton bouton(2);   // entrée lançant une tempo multiple 1 sur sorties 6,10 et 12
const int Sw = 3;            // entrée lançant une tempo 2 unique sur sortie 12 (Lect)
const int Lect = 12;                             
int tempoActive =0;                   
unsigned long tempoDepart = 0;           
bool lancerSequence = false;

void gererSequence()
{
 static byte etape = 0;
 static unsigned long chrono = 0;
 unsigned long delai = millis() - chrono;


 
 if (etape == 0 && lancerSequence)
 {
  Serial.println(F("Debut sequence")); 
  lancerSequence = false;
   
digitalWrite(10,HIGH);
digitalWrite(6,HIGH);
   etape++;
   chrono = millis();
   } 
 
 else if (etape == 1 && delai >= 1000)
 {
   digitalWrite(12,HIGH);
   etape++;
   chrono = millis();
 }
 else if (etape == 2 && delai >= 500)
 {
   digitalWrite(12,LOW);
   etape++;
   chrono = millis();
 }
 else if (etape == 3 && delai >= 500)
 {
   digitalWrite(12,HIGH);
   etape++;
   chrono = millis();
 }
 else if (etape == 4 && delai >= 500)
 {
  digitalWrite(12,LOW); 
  etape++;
  chrono = millis();
 }
 else if (etape == 5 && delai >= 1000)
 
 {
  digitalWrite (10,LOW); 
  etape++;
  chrono = millis();
 }
 else if (etape == 6 && delai >= 3000)

 {
 digitalWrite(6,LOW);
 Serial.println(F("Fin sequence"));
   
 
   etape == 0;                                       // l'erreur de code était ici
   
    
  }
 
}
 
void gererBouton()
{
  static bool repos = true;
 
  bouton.actualiser();

  if (repos && bouton.estEnfonceDepuisAuMoins(5000))
  lancerSequence=true;
  {
   
}
}
void setup(){
  pinMode(bouton,INPUT);
  pinMode(10,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(6,OUTPUT); 
  pinMode(Sw,INPUT_PULLUP);           
  pinMode(Lect,OUTPUT);                 
}

void loop(){

  gererBouton();

   gererSequence();


 
   if(digitalRead(Sw) ==LOW)digitalWrite(Lect,HIGH);  // si bouton Lecture enfoncé,déclenche alim modules recorder et ampli BF

if(digitalRead(Sw)==LOW) {
  tempoActive = 1;
  tempoDepart = millis();
}
if(tempoActive)
if((millis()-tempoDepart)>=10000){
  digitalWrite(Lect,LOW);
  tempoActive=0;

}
}

etape == 0; // l'erreur de code était ici

Faux, cette ligne n'a aucune utilité. La supprimer reviendrait au même.

Je veux bien admettre, or il s'avère qu'en écrivant le code ainsi, les sorties 10 et 12 ne font plus deux boucles successives, alors que la sortie 6 ne le fait qu'une fois.

En supprimant la ligne, c'est encore pire.

En résumé, avec etape==0 , j'ai successivement, 6 et 10 =1, 10 =0, 12=1,12=0,12=1,12=0 et 6=0, fin de boucle,ce que je recherche à obtenir.

Avec etape = 0; j'ai successivement,6 et 10 =1, 10 =0, 12=1,12=0,12=1,12=0 suivi de 10 =1, 10 =0, 12=1,12=0,12=1,12=0 et enfin 6=0 qui clôture la boucle.

y aurait-il une autre hypothèse pour ce phénomène, dans ce cas?

Quand on débute, c'est une bonne habitude à prendre d'afficher le déroulement d'un sketch avec des Serial.print() et Serial.println().
Avec un Serial.begin() dans setup() bien entendu.

j'en prends note.

Mais la cause du problème constaté n'est pas là précisément? c'est juste pour détailler le déroulement du programme?

Pourquoi, selon vous cette ré-écriture sorties 10 et 12?