Comment fait-on pour arrêter la boucle ?

Bonjour a tous, je suis un amateur dans le domaine de la programmation par contre je maîtrise la programmation d'automates.

Bref, je me suis lancé dans le défi de remplacer un automate par un arduino.

Mon programme doit être capable lorsque l'on activé une des entre ( pin2) lancer une séquence :active en même temps 3 sorties pendant 2seconds puis les eteindrent puis allumer un sortie pendant 2 seconds puis de l'éteindre.

Jusque la j'ai réussi à le faire fonctionner mais mon entrée est un interrupteur ( ou bistable ) et de ce faite mon programme boucle la séquence tout le temps j'aimerais qui ne tienne compte que du changement d'état ( comme un front montant ou front descendant )

Merci d'avance

Ps: je suis un autodidacte et je suis qu'un débutant merci de votre compréhension

while (digitalRead(tonEntrée) == false) {
  
}

Non ?

Chrysystem:
Bonjour a tous, je suis un amateur dans le domaine de la programmation par contre je maîtrise la programmation d'automates.

J'ai du mal à comprendre comment c'est possible... La logique de programmation d'un automate ou d'un arduino est totalement identique.
M'enfin, pour répondre, soit tu fais comme l'a dit Geeker soit tu utilises break combiné à un if ou un switch à l'intérieur de la boucle.

j'aimerais qui ne tienne compte que du changement d'état ( comme un front montant ou front descendant )

Pour détecter un front, il faut tester l'état de l'entrée à 2 instants différents. Par exemple l'état à l'instant présent et l'état lors du passage précédent dans la boucle. Ensuite on compare si l'état actuel est l'état précéddent sont différents. Si c'est le cas alors il y a eu un front.

byte monEntree=2;

byte actuel;
byte precedent;

void setup(void){
  Serial.begin(9600);
  pinMode(monEntree, INPUT);
  precedent=digitalRead(monEntree);  // pour initialiser la variable dans un état connu
}

void loop(void){
  actuel=digitalRead(monEntree);    // Lit l'état de l'entrée
  if (actuel!=precedent){           // Si différent il y a eu changement d'état
    Serial.print("il y a eu une transition "); // Cette condition teste toutes les transitions
  }
  
  if ((actuel==0) && (precedent==1)){ // si precedent à 1 et actuel à 0 front descendant
    Serial.println("descendante");         // Cette condition teste les fronts descendants
  }
  if ((actuel==1) && (precedent==0)){ // si precedent à 0 et actuel à 1 front descendant
    Serial.println("montante");         // Cette condition teste les fronts montants
  }
  precedent = actuel;                // mémorise l'état actuel pour la prochaine itération
  delay(500);                          // pour les besoins de la démonstration mettre ici le reste du code
}

Bonjour,

En gros tu veut détecter un front montant sur la broche D2 ?
Utilise attachInterrupt() pour mettre un "flag" (variable booléenne) à True et dans ton loop() gére ta séquence dés qu'il passe à True :wink:

Exemple :

bool flag = False;

void intBouton() {
  flag = True;
}

void setup() {
  attachInterrupt(0, intBouton, RISING);
}

void loop() {
  while(flag == False);
  
  // Gère ta séquence

  flag = False;
}

Merci a tous pour vos post

vohu:

Chrysystem:
Bonjour a tous, je suis un amateur dans le domaine de la programmation par contre je maîtrise la programmation d'automates.

J'ai du mal à comprendre comment c'est possible... La logique de programmation d'un automate ou d'un arduino est totalement identique.
M'enfin, pour répondre, soit tu fais comme l'a dit Geeker soit tu utilises break combiné à un if ou un switch à l'intérieur de la boucle.

pour répondre a ta question mon problème ne réside pas dans la logique mais dans le programme ( le langage ) je n'ai pratiquement pas fais de langage C j'apprend sur le tas

je pense que pour que se soit plus simple pour vous je vais vous mettre mon programme

/*test de programmation ID d'allée*/
// set pin :
const int bistable1 = 2; // Bistable reconnaissance d'allée
const int bistable2 = 4; // bistable reconnaissance d'allée Nisveau 2
const int id1 = 7; // entrée Mcu id d'allée 
const int id2 = 12; // entrée Mcu id d'allée
const int id3 = 13; // entrée Mcu id d'allée
// Les variables
const int activ = 0;
const int No_activ = 1;
const int ON = 1;
const int OFF = 0;
int bist1state = 0; // statue du bistable 1
int bist2state = 0; // statue du bistable 2

void setup() {
  // initilisation des sorties carte:
  pinMode(id1, OUTPUT);
  pinMode(id2, OUTPUT);
  pinMode(id3, OUTPUT);
  // initialisation des entrées:
 pinMode(bistable1, INPUT);
 pinMode(bistable2, INPUT);
 digitalWrite(bistable1, HIGH); //rappel pullup au + du bistable
 digitalWrite(bistable2, HIGH); //rappel pullup au + du bistable
}
//Programme:
void loop (){
  // lecture des etats des bistables:
  // check l'etat des bistables.
  // si le bistable 1 et actif alors fais la sequence suivant:
  bist1state = digitalRead(bistable1);
  bist2state = digitalRead(bistable2);
  
  // lance la sequence 1.
  if (bist1state == activ && bist2state == No_activ)
  { 
    digitalWrite(id1, HIGH);
    digitalWrite(id2, HIGH);
    digitalWrite(id3, HIGH);
    delay(2000);
    digitalWrite(id1, LOW);
    digitalWrite(id2, LOW);
    digitalWrite(id3, LOW);
    delay(2000);
    digitalWrite(id1, HIGH);
    delay(2000);
    digitalWrite(id1, LOW);

  }
  // lance sequence 2.
  if (bist1state == No_activ && bist2state == activ)
  {
    digitalWrite(id1, HIGH);
    delay(2000);
    digitalWrite(id1, LOW);
    delay(2000);
    digitalWrite(id1, HIGH);
    digitalWrite(id2, HIGH);
    digitalWrite(id3, HIGH);
    delay(2000);
    digitalWrite(id1, LOW);
    digitalWrite(id2, LOW);
    digitalWrite(id3, LOW);
   
  }
  
   
    
    
    
  // les capteus sont au repos
 if (bist1state == No_activ && bist2state == No_activ) 
{
  
    // off
    digitalWrite(id1, OFF);
    digitalWrite(id2, OFF);
    digitalWrite(id3, OFF);
    
  
}
}

mon problème est que tant que mon capteur est a 1 le programme répète la même séquence alors que je veux qu'il ne la fasse qu'une fois ou lors d'un changement d'état

Merci encore pour votre aide

Il faut simplement utiliser une variable qui mémorise l'état précédent de ta condition, mise à jour à chaque fin de boucle par exemple.
Ensuite tu ajoutes un test sur cette variable pour savoir si lors de l'itération courante, tu viens de changer d'état.

Bon et bien merci,

finalement j'ai trouvé ma solution, en mémorisant mon état en fin d'un condition.

Merci encore pour vos conseils.

pour ceux que sa intéresse je met mon programme histoire de comprendre sur ce Salut et a bientôt :grin: XD

/* test de programmation
Deux capteurs

*/
// set pin :
const int bistable1 = 2; // Bistable reconnaissance d'allée
const int bistable2 = 3;// bistable reconnaissance d'allée Nisveau 2
byte etat; // memorisation de l'etat de la sequence 1
byte etat2; // memoristion de l'etat de la sequence 2
byte bst1;
byte bst2;
const int id1 = 7; // entrée Mcu id d'allée
const int id2 = 12; // entrée Mcu id d'allée
const int id3 = 13; // entrée Mcu id d'allée
// Les variables

const int activ = 0;
const int No_activ = 1;
const int ON = 1;
const int OFF = 0;
int bist1state = 0; // statue du bistable 1
int bist2state = 0; // statue du bistable 2

void setup() {
// initilisation des sorties carte:
pinMode(id1, OUTPUT);
pinMode(id2, OUTPUT);
pinMode(id3, OUTPUT);
// initialisation des entrées:
pinMode(bistable1, INPUT);
pinMode(bistable2, INPUT);
digitalWrite(bistable1, HIGH); //rappel pullup au + du bistable
digitalWrite(bistable2, HIGH); //rappel pullup au + du bistable

}
//Programme:
void loop (){
// lecture des etats des bistables:
// check l'etat des bistables.
// si le bistable 1 et actif alors fais la sequence suivant:
bist1state = digitalRead(bistable1);
bist2state = digitalRead(bistable2);

// lance la sequence 1.
if ((bist1state == activ) && (bist2state == No_activ)){
bst1 = 1;
}

if ((bist1state == No_activ) && (bist2state == activ))

{
bst2 = 1;
}

if ( bst1 ==1 && etat == 0 )
{
digitalWrite(id1, HIGH);
digitalWrite(id2, HIGH);
digitalWrite(id3, HIGH);
delay(2000);
digitalWrite(id1, LOW);
digitalWrite(id2, LOW);
digitalWrite(id3, LOW);
delay(2000);
digitalWrite(id1, HIGH);
delay(2000);
digitalWrite(id1, LOW);
etat = 1;

}
// lance sequence 2.
if (bst2 == 1 && etat2 == 0)

{
digitalWrite(id1, HIGH);
delay(2000);
digitalWrite(id1, LOW);
delay(2000);
digitalWrite(id1, HIGH);
digitalWrite(id2, HIGH);
digitalWrite(id3, HIGH);
delay(2000);
digitalWrite(id1, LOW);
digitalWrite(id2, LOW);
digitalWrite(id3, LOW);
etat2 = 1;

}

// les capteus sont au repos
if ((bst1 == 0) && (bst2 == 0))
{

// off
digitalWrite(id1, OFF);
digitalWrite(id2, OFF);
digitalWrite(id3, OFF);
etat = 0;
etat2 = 0;

}
bst1 = 0;
bst2 = 0;
}

vohu:

Chrysystem:
Bonjour a tous, je suis un amateur dans le domaine de la programmation par contre je maîtrise la programmation d'automates.

J'ai du mal à comprendre comment c'est possible... La logique de programmation d'un automate ou d'un arduino est totalement identique.
M'enfin, pour répondre, soit tu fais comme l'a dit Geeker soit tu utilises break combiné à un if ou un switch à l'intérieur de la boucle.

Justement non, il y'a pleins de choses que fait l'OS de l'automate

D'abords la com' avec ses cartes, puis la console, puis la supervision.
Ensuite la recopie des entrées en mémoire, la gestion des temporisation internes, parfois la gestion des fronts (pour les API qui savent faire, et si le programme les utilise (perso je les programme a la main mes fronts. Des fois je programme aussi mes tempos a la main, c'est plus pratique pour la supervision))
Ensuite l’exécution du programme de l'utilisateur.
Ensuite seulement la mise a jour des sorties physiques (via parfois un coup de com avec les cartes, mais en évitant le doublon avec ce qu'il fait en début de cycle)
Puis enfin un rebouclage.

Ajoute a cela les taches sous interruptions qui ont une gestion particulière, et la prog d'initialisation au premier cycle.

On peut utiliser un arduino pour remplacer un automate, mais il faut y rajouter un mini OS qui gère les trucs en plus dont on a besoin (on a pas forcement besoin de toutes les fonctions d'un automate).