Auteur Sujet: Automate embarqué  (Lu 871 fois)

peyo

  • Newbie
  • *
  • Messages: 22
    • Voir le profil
Re : Automate embarqué
« Réponse #15 le: juillet 08, 2018, 09:46:52 am »
Citer
ligne 71 le else n'est pas logique.

J'ai trouvé cette bidouille dans un exemple sur le net, et sans ce ELSE IF, le moteur démarre à l'appuis sur le bouton puis s'arrête d'un coup..

Je ne comprends pas pourquoi d'ailleurs mais avec le else ça fonctionne !

peyo

  • Newbie
  • *
  • Messages: 22
    • Voir le profil
Re : Automate embarqué
« Réponse #16 le: juillet 08, 2018, 09:58:21 am »
Citer
tu testes l'état du bouton (qui peut fluctuer énormément car il y a des rebonds
Dominique, J'ai monté mon bouton un pull up, (à ce qu'il parait) c'est moins pire?

J'ai essayé d’insérer bounce 2 mais rien ne fonctionne, je ne comprends pas..
(j'ai même cramé une UNO en modifiant le câblage après un C-C sur l'alim stabilisé 12v :-( ..)


//Automate pour navette train plus arret en gare.
// commande automatismes par lecture de gadges RFID sur la voie
#include <Bounce2.h>
#include <SPI.h>
#include <RFID.h>

RFID RFID(10,9);
int UID[5]={};
int Gare1[5]={34,199,71,115,209};  // badge gare 1
int Gare2[5]={60,111,82,115,114};  //badge gare 2
int Fin1[5]={17,17,76,115,63};     //badge Fin de voie 1
int Fin2[5]={176,247,96,131,164};  //badge Fin de voie 2
int pinLedsens1, pinLedsens2;
//gestion du pont en H
int IN1 = 5; // commande pont en H "1"
int IN2 = 6; // commande pont en H "2"

// Création d'un objet Bounce que j'appelle bouton
Bounce bouton;
const byte bp = 2;
 
int a; //rapport cyclique entre 0 et 255
 // tableau des machines à états
 enum {sens1, sens2 } etatloco ;
 enum {Marche, Stop  } etatmoteur ;
 
 //////////////////////////////////////////////////////////////
void setup() {
 
  Serial.begin(9600);
  SPI.begin();
  RFID.init();
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
 
  //leds avant arrière sur pin 3 et 4 :
  pinLedsens1 = 3;
  pinLedsens2 = 4;
 
  pinMode(bp,INPUT_PULLUP);
 
  // definition des paramètres de l'objet Bounce
  bouton.attach(bp);   // la broche du bouton poussoir
  bouton.interval(10); // l'intervalle de temps en ms
 
  pinMode(pinLedsens1, OUTPUT);//sens 1 = led avant blanche et arrière rouge
  pinMode(pinLedsens2, OUTPUT); //sens 2 = led avant rouge et arrière blanche
 
   
  // initialisation du moteur vitesse à 0
  digitalWrite(IN2, 0);
  digitalWrite(IN1, 0);
 
 // Initialisation des états
 etatloco = sens1 ;
 etatmoteur = Stop ;
 // initialisation du facteur d'incrémentation moteur
 a=0;
 
 // Initialisation des leds (feux du train en sens 1)
  digitalWrite(pinLedsens1,HIGH);
  digitalWrite(pinLedsens2,LOW);
}

void loop()

   // l'objet Bounce doit exécuter son code interne à chaque loop :
  bouton.update();
   // Lire la valeur du bp filtré :
  int value = bouton.read();
 
if (value == LOW && etatmoteur == Stop ) //marche
{
  a=0;
 
ACCELERATION_SENS1();
a=255;
etatmoteur = Marche;
etatloco = sens1 ;
value = HIGH;
delay (100) ;
}


else if (value == LOW && etatmoteur == Marche)// Arret
{
  a=255;
  STOP_moteur();
  etatmoteur = Stop;
  value = HIGH;
   delay (100) ;
 }
 
// Recherche de badges RFID sur la voir
   if (RFID.isCard() && etatmoteur == Marche) { 

          /* Lecture du tag */
          if (RFID.readCardSerial())
          {       
          /*Serial.print("L'UID est: ");*/ 
            for(int i=0;i<=4;i++)
            {
              UID[i]=RFID.serNum[i];
             /* Serial.print(UID[i],DEC);
              Serial.print(".");*/
            }
            /*Serial.println("");*/
          }
          /* fin de  Lecture du tag */
         
          if (UID[0] == Gare1[0]// si lecture du badge Gare 1
           && UID[1] == Gare1[1]   
           && UID[2] == Gare1[2]   
           && UID[3] == Gare1[3]   
           && UID[4] == Gare1[4]
           && etatloco == sens1)
            {
              a=255 ;
             DECCELERATION_SENS1();
          delay (2000);
          a=0;
          ACCELERATION_SENS1() ;
          etatloco = sens1 ;
           
            }
           
          if (UID[0] == Gare2[0] // si lecture du badge Gare 2
           && UID[1] == Gare2[1]   
           && UID[2] == Gare2[2]   
           && UID[3] == Gare2[3]   
           && UID[4] == Gare2[4]
           && etatloco == sens2) 
            {
              a=255 ;
          DECCELERATION_SENS2();
          delay (2000);
          a=0;
          ACCELERATION_SENS2() ;
          etatloco = sens2 ;
            }
           
          if (UID[0] == Fin1[0] // si lecture du badge fin de voie 1 
           && UID[1] == Fin1[1] 
           && UID[2] == Fin1[2]   
           && UID[3] == Fin1[3]   
           && UID[4] == Fin1[4]
           && etatloco == sens1) 
            {
             a=255 ;
             DECCELERATION_SENS1();
          delay (2000);
          digitalWrite(pinLedsens2,HIGH); //inversement des feux rouge en blanc
          digitalWrite(pinLedsens1,LOW);
          delay (1000) ;
          a=0;
          ACCELERATION_SENS2() ;
          etatloco = sens2 ;
            }
           
          if (UID[0] == Fin2[0] // si lecture du badge fin de voie 2 
           && UID[1] == Fin2[1]   
           && UID[2] == Fin2[2]   
           && UID[3] == Fin2[3]   
           && UID[4] == Fin2[4]
           && etatloco == sens2)   
            {
              a=255 ;
             
             DECCELERATION_SENS2();
          delay (2000);
          digitalWrite(pinLedsens1,HIGH);
          digitalWrite(pinLedsens2,LOW);
          delay (1000) ;
          a=0;
          ACCELERATION_SENS1() ;
          etatloco = sens1 ;
            }
           
          RFID.halt();
    }
    delay(100);   
}

void STOP_moteur()//en cas de problème ou pour éteindre l'automate
{
 analogWrite(IN1, 0) ;
 analogWrite(IN2, 0) ;

}
void ACCELERATION_SENS1()
{
  while (a <=255)
  { // phase d'accélération.
   analogWrite(IN1, a);
   a = a + 1;
   delay(20);
 }
}

void DECCELERATION_SENS1()
{
  while (a >=0) { // phase de décélération
   analogWrite(IN1, a);

   a = a - 1;
   delay(20);
  }
}
void ACCELERATION_SENS2()
{
 while (a <=255)
  { // phase d'accélération.
   analogWrite(IN2, a);
   a = a + 1;
   delay(20);
 }
}

void DECCELERATION_SENS2()
{
  while (a >=0)
  { // phase d'accélération.
   analogWrite(IN2, a);
   a = a - 1;
   delay(20);
 }
}

msport

  • Sr. Member
  • ****
  • Messages: 416
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Automate embarqué
« Réponse #17 le: juillet 08, 2018, 10:07:58 am »
le else élimine le cas Etat bouton == HIGH

pour voir où on passe dans le programme, il faut y placer des mouchards avec des Serial.print avec les variables concernées.
Cordialement

msport

  • Sr. Member
  • ****
  • Messages: 416
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : Re : Automate embarqué
« Réponse #18 le: juillet 08, 2018, 10:10:50 am »
j'ai même cramé une UNO en modifiant le câblage après un C-C sur l'alim stabilisé 12v :-( ..)

cause de décès prématuré bien connue. RIP.
Cordialement

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1297
  • 100% Arduino et N
    • Voir le profil
Re : Automate embarqué
« Réponse #19 le: juillet 08, 2018, 07:46:42 pm »
Bonsoir peyo,

Voici une version améliorée de ton sketch :
//Automate pour navette train plus arret en gare.
// commande automatismes par lecture de gadges RFID sur la voie
#include <Bounce2.h>
#include <SPI.h>
#include <RFID.h>

RFID RFID(10,9);
int UID[5]={};
int Gare1[5]={34,199,71,115,209};  // badge gare 1
int Gare2[5]={60,111,82,115,114};  //badge gare 2
int Fin1[5]={17,17,76,115,63};     //badge Fin de voie 1
int Fin2[5]={176,247,96,131,164};  //badge Fin de voie 2

// Création d'un objet Bounce que j'appelle bouton
const int pinBp = 2;
Bounce bouton = Bounce();

// leds de sens
const int pinLedsens1 = 3;
const int pinLedsens2 = 4;

//gestion du pont en H
const int pinIN1 = 5; // commande pont en H "1"
const int pinIN2 = 6; // commande pont en H "2"

//vitesse moteur : rapport cyclique entre 0 et 255
int a = 0;

// tableau des machines à états
enum {sens1, sens2 } etatloco ;
enum {Marche, Stop } etatmoteur ;
enum {nulpart, posGare1, posGare2, posFin1, posFin2} posloco;
 
 //////////////////////////////////////////////////////////////
void setup() {
 
  Serial.begin(9600);
  SPI.begin();
  RFID.init();
  pinMode(pinIN1, OUTPUT);
  pinMode(pinIN2, OUTPUT);

  // initialisation du moteur vitesse à 0
  digitalWrite(pinIN1, 0);
  digitalWrite(pinIN2, 0);

  //leds avant arrière sur pin 3 et 4 :
  pinMode(pinLedsens1, OUTPUT);//sens 1 = led avant blanche et arrière rouge
  pinMode(pinLedsens2, OUTPUT); //sens 2 = led avant rouge et arrière blanche
  // Initialisation des leds (feux du train en sens 1)
  digitalWrite(pinLedsens1,HIGH);
  digitalWrite(pinLedsens2,LOW);
 
 
  // definition des paramètres de l'objet Bounce
  pinMode(pinBp,INPUT_PULLUP);
  bouton.attach(pinBp);   // la broche du bouton poussoir
  bouton.interval(20); // l'intervalle de temps en ms
 
 
  // Initialisation des états
  etatloco = sens1 ;
  etatmoteur = Stop ;
  posloco = nulpart;
 
  // initialisation du facteur d'incrémentation moteur ???
  a=0; // mais c'est déjà fait dans la déclaration
 
}

///////////////// UTILITAIRES ////////////
void STOP_MOTEUR()  //en cas de problème ou pour éteindre l'automate
{
 analogWrite(pinIN1, 0) ;
 analogWrite(pinIN2, 0) ;

}

void ACCELERATION_SENS1()
{
  while (a < 255)
  { // phase d'accélération sens 1
    a++;
    analogWrite(pinIN1, a);
    delay(20);
  }
}

void DECCELERATION_SENS1()
{
  while (a > 0)
  { // phase de décélération sens 1
    a--;
    analogWrite(pinIN1, a);
    delay(20);
  }
}

void ACCELERATION_SENS2()
{
  while (a < 255)
  { // phase d'accélération sens 2
    a++;
    analogWrite(pinIN2, a);
    delay(20);
  }
}

void DECCELERATION_SENS2()
{
  while (a > 0)
  { // phase d'accélération sens 2
   a--;
   analogWrite(pinIN2, a);
   delay(20);
 }
}


void loop()

  // l'objet bouton doit exécuter son code interne à chaque loop :
  bouton.update();
  // lecture du bouton et execution à chaque enfoncement
  if (bouton.fell())
  {
    if (etatmoteur == Stop) // acceleration et marche
    {
      // demarrage depuis la vitesse 0 (stop)
      a = 0;
      ACCELERATION_SENS1();
      etatmoteur = Marche;
      etatloco = sens1 ;
      delay (100) ;
    } else // (etatmoteur == Marche) : stop
    {
      // arrêt immediat du moteur
      STOP_MOTEUR();
      a = 0;
      etatmoteur = Stop;
      delay (100) ;
    }
  }
   
 
  // Recherche de badges RFID sur la voie, uniquement en marche
  if (RFID.isCard() && etatmoteur == Marche)
  { 

    /* Lecture du tag */
    if (RFID.readCardSerial())
    {       
      /*Serial.print("L'UID est: ");*/ 
      for (int i=0;i<=4;i++)
      {
        UID[i]=RFID.serNum[i];
        // Serial.print(UID[i],DEC);Serial.print(".");
      }
      //Serial.println("");
    }/* fin de  Lecture du tag */
    RFID.halt();
  }

  // recherche de la position
  posloco = nulpart;
  for (int i=0;i<=4;i++)
    {     
      if (UID[i] == Gare1[i]) // si lecture du badge Gare 1
      {
        posloco = posGare1;
      } else {
        posloco = nulpart;
        break; // sortie de la boucle for car une des valeurs est fausse
      }
    }
  for (int i=0;i<=4;i++)
    {     
      if (UID[i] == Gare2[i]) // si lecture du badge Gare 2
      {
        posloco = posGare2;
      } else {
        posloco = nulpart;
        break; // sortie de la boucle for car une des valeurs est fausse
      }
    }
  for (int i=0;i<=4;i++)
    {     
      if (UID[i] == Fin1[i]) // si lecture du badge Fin de voie 1
      {
        posloco = posFin1;
      } else {
        posloco = nulpart;
        break; // sortie de la boucle for car une des valeurs est fausse
      }
    }
  for (int i=0;i<=4;i++)
    {     
      if (UID[i] == Fin2[i]) // si lecture du badge Fin de voie 2
      {
        posloco = posFin2;
      } else {
        posloco = nulpart;
        break; // sortie de la boucle for car une des valeurs est fausse
      }
    }
             
  switch (posloco)
  {
    case posGare1 :
      a=255 ;
      DECCELERATION_SENS1();
      delay (2000);
      a=0;
      ACCELERATION_SENS1() ;
      etatloco = sens1 ;
    break;
    case posGare2 :
      a=255 ;
      DECCELERATION_SENS2();
      delay (2000);
      a=0;
      ACCELERATION_SENS2() ;
      etatloco = sens2 ;
    break;
    case posFin1 :
      if (etatloco == sens1) 
      {
        a=255 ;
        DECCELERATION_SENS1();
        delay (2000);
        digitalWrite(pinLedsens2,HIGH); //inversement des feux rouge en blanc
        digitalWrite(pinLedsens1,LOW);
        delay (1000) ;
        a=0;
        ACCELERATION_SENS2() ;
        etatloco = sens2 ;
      }
    break;
    case posFin2 :
      if (etatloco == sens2)   
      {
        a=255 ;
        DECCELERATION_SENS2();
        delay (2000);
        digitalWrite(pinLedsens1,HIGH);
        digitalWrite(pinLedsens2,LOW);
        delay (1000) ;
        a=0;
        ACCELERATION_SENS1() ;
        etatloco = sens1 ;
      }         
    break;     
  }
           
  //delay(100);   
}


Les améliorations sont les suivantes :

- les définitions et déclarations sont mieux classées et les pins de l'Arduino sont déclarées en const int.
- j'ai préfixé chaque pin des lettres "pin".
- l'objet bouton était mal déclaré : Bounce bouton = Bounce();
- j'ai ajouté une variable d'état : enum {nulpart, posGare1, posGare2, posFin1, posFin2} posloco;

Ceci permet de traiter indépendamment les 3 actions de ta loop (la lecture du bouton, la reconnaissance RFID et l'action qui en découle.

- j'ai remonté tes fonctions utilitaires entre le setup() et la loop() car c'est mieux de déclarer quelque chose AVANT de s'en servir (même si le compilateur ne proteste pas, crois moi, il protestera un de ces jours quand ton code va grossir !).
Je les ai modifiées pour les rendre plus claires.

La loop() est composée de 3 parties qui s'exécutent l'une après l'autre :

La lecture du bouton :
Seul l'enfoncement est pris en compte. Un appui, ça démarre, un appui ça s'arrête.
Il faudra que tu regardes ce que tu voulais exactement pour initialiser la variable "a" ou pas selon le résultat attendu

La lecture du RFID : elle donne un résultat qui est TOUJOURS un des cas de l'enum "posloco".
C'est "nulpart" quand une des valeurs est fausse.

Ensuite le traitement de la position : si c'est nulpart, elle ne fait rien (il n'y a pas de "case nulpart").
Donc dès qu'il y a une détection valide, l'un des cas du switch s'éxécute.

Il faudra que tu revoies les exécutions des cas dans le switch et que tu simplifies ou corriges. C'est là que ton programme fait le boulot principal.

Amicalement
Dominique

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1297
  • 100% Arduino et N
    • Voir le profil
Re : Automate embarqué
« Réponse #20 le: juillet 08, 2018, 09:17:41 pm »
Bon je n’ai probablement pas pris le temps de tout vérifier, donc il reste sûrement des erreurs.

Par exemple, la recherche de la position doit être dans le « if (RFID.iscard()) » sinon le traitement de la balise précédente va se répéter jusqu’à la suivante.

Bon je te laisse chercher les autres ...

peyo

  • Newbie
  • *
  • Messages: 22
    • Voir le profil
Re : Automate embarqué
« Réponse #21 le: juillet 12, 2018, 10:25:14 pm »
Merci Dominique pour ton aide,
Je ne serais pas dispo cet été pour bosser sur ce programme mais dès la rentrée je m'y replonge !!!
Effectivement le bouton fonctionne bien mais les badges ne sont pas détectés.

Bonnes vacances à tous et bon courage pour ceux qui comme moi, bossent dur tout l'été !!