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