Go Down

Topic: Comment fait-on pour arrêter la boucle ? (Read 1 time) previous topic - next topic

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

Geeker

Code: [Select]

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

Non ?
Codeur en Lua, python, java, C,  Arduino, un peu d'assembleur ...

vohu


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.

fdufnews

#3
Apr 21, 2013, 11:24 am Last Edit: Apr 21, 2013, 11:58 am by fdufnews Reason: 1
Quote
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.

Code: [Select]
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
}

skywodd

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 ;)

Exemple :
Code: [Select]
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;
}
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Merci a tous pour vos post


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

#6
Apr 21, 2013, 12:08 pm Last Edit: Apr 21, 2013, 02:37 pm by Jean-François Reason: 1
je pense que pour que se soit plus simple pour vous je vais vous mettre mon programme

Code: [Select]

/*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

patg_

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.
Mes Arduineries: http://breizhmakers.over-blog.com/

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  :smiley-mr-green: 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;
}
 

MiGaNuTs



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).

Go Up