Bonjour
CA MARCHE !!!!
Juste à temps pour le réveillon, mon train fonctionne presque comme je le voulais...
Je n'arrive pas à modifier la vitesse de croisière mais je reverrai cela début janvier (la fin de l'année est très chargée)
Pour ceux qui le souhaite, voici mon programme arduino
#include <Encoder.h>
#include <ACS712.h>
//la représentation physique du rail
// G -- 1 -- 2 -- 3 -- C -- 4 -- 5 -- 6 -- 7 -- D
//Les pins
int pinZG = A0; /*détecteur gare G*/
int pinZ1 = A5; /*détecteur zone 1*/
int pinZ2 = 12; /*détecteur zone 2*/
int pinZ3 = 11; /*détecteur zone 3*/
int pinZC = A1; /*détecteur gare C*/
int pinZ4 = 10; /*détecteur zone 4*/
int pinZ5 = 9; /*détecteur zone 5*/
int pinZ6 = 8; /*détecteur zone 6*/
int pinZ7 = 7; /*détecteur zone 7*/
int pinZD = A2; /*détecteur gare D*/
int pinACS = A3; /*capteur de courant*/
int pinEncP = 2; /*bouton poussoir de l'encodeur - AVEC UNE INTERRUPTION */
int pinEncS = 1; /*encodeur sens de rotation*/
int pinEncR = 3; /*encodeur rotation - AVEC UNE INTERRUPTION */
int pinPWM = 6; /*enB du OKY3195*/
int pinS1 = 5; /*sens direct du courant OKY3195 */ /*ATENTION : ne jamais avoir pinS1 et pinS2 à HIGH en même temps*/
int pinS2 = 4; /*sens opposé du courant OKY3195 */ /*ATENTION : ne jamais avoir pinS1 et pinS2 à HIGH en même temps*/
int pinSeed = A4; /*pour le grain de folie aléatoire*/
Encoder myEnc(pinEncS,pinEncR); /*déclaration de l'encodeur pour la bibliothèque Encoder.h*/
ACS712 sensor(ACS712_05B, pinACS); /* declaration du capteur de courant*/
//Les énumérations
enum zones {gareG,zone1,zone2,zone3,gareC,zone4,zone5,zone6,zone7,gareD}; /*les différentes zones (cantons)*/
enum vitesses {STOP, LENT, ACC, RAPIDE, RAL}; /*les différentes vitesses possibles*/
enum trajets {GC,CG,DC,CD,GD,DG}; /*Les différents trajets possibles (GC = de G à C)*/
/*les différentes allures en fonction des trajets*/
/* G 1 2 3 C 4 5 6 7 D */
const int allures[][10] = {{LENT , ACC , RAPIDE , RAL , STOP , STOP , STOP , STOP , STOP , STOP}, /*le trajet GC*/
{STOP , RAL , RAPIDE , ACC , LENT , STOP , STOP , STOP , STOP , STOP}, /*le trajet CG*/
{STOP , STOP , STOP , STOP , STOP , LENT , RAL , RAPIDE , ACC , LENT}, /*le trajet DC*/
{STOP , STOP , STOP , STOP , LENT , LENT , ACC , RAPIDE , RAL , STOP}, /*le trajet CD*/
{LENT , ACC , RAPIDE , RAL , LENT , LENT , ACC , RAPIDE , RAL , STOP}, /*le trajet GD*/
{STOP , RAL , RAPIDE , ACC , LENT , LENT , RAL , RAPIDE , ACC , LENT}}; /*le trajet DG*/
const int sens[6] = {1,-1,-1,1,1,-1}; /* les sens de trajet : 1 = de G vers D ; -1 = de D vers G */
//les variables
long maxSpeed = 200; /* la vitesse maximale (entre 0 et 250 en PWM) que pourra atteindre le train dans les phases RAPIDE*/
const long minSpeed = 100; /*la vitesse du train dans les phases LENT et au redémarrage*/
long theSpeed;
long stepSpeed =20;
boolean isON = true; /* pour le bouton poussoir : isON = true -> le train a le droit de rouler ; isON = false -> arret d'urgence (PWM à 0)*/
const unsigned long antiRebond = 3; /*délai pour l'anti rebond du bouton poussoir */
int currentTrip;
boolean endTrip;
int currentZone =-999;
//Les fonctions
/*pour changer l'aléatoire de random*/
byte getSeed()
{
byte seed = 0;
byte i = 8;
while (i > 0)
{
byte firstBit = analogRead(pinSeed) & 0x01;
byte secondBit = analogRead(pinSeed) & 0x01;
if (firstBit != secondBit)
{
seed = (seed << 1) | firstBit;
i--;
}
}
return seed;
}
/*pour savoir où est le train*/
int WhereIsMyTrain(int theZone)
{
switch(theZone)
{
case gareG:
if (digitalRead(pinZ1)==0) {return zone1;}
else {return currentZone;}
break;
case zone1:
if (digitalRead(pinZG)==0) {return gareG;}
else if(digitalRead(pinZ2)==0) {return zone2;}
else {return currentZone;}
break;
case zone2:
if (digitalRead(pinZ1)==0) {return zone1;}
else if(digitalRead(pinZ3)==0) {return zone3;}
else {return currentZone;}
break;
case zone3:
if (digitalRead(pinZ2)==0) {return zone2;}
else if(digitalRead(pinZC)==0) {return gareC;}
else {return currentZone;}
break;
case gareC:
if (digitalRead(pinZ3)==0) {return zone3;}
else if(digitalRead(pinZ4)==0) {return zone4;}
else {return currentZone;}
break;
case zone4:
if (digitalRead(pinZC)==0) {return gareC;}
else if(digitalRead(pinZ5)==0) {return zone5;}
else {return currentZone;}
break;
case zone5:
if (digitalRead(pinZ4)==0) {return zone4;}
else if(digitalRead(pinZ6)==0) {return zone6;}
else {return currentZone;}
break;
case zone6:
if (digitalRead(pinZ5)==0) {return zone5;}
else if(digitalRead(pinZ7)==0) {return zone7;}
else {return currentZone;}
break;
case zone7:
if (digitalRead(pinZ6)==0) {return zone6;}
else if(digitalRead(pinZD)==0) {return gareD;}
else {return currentZone;}
break;
case gareD:
if (digitalRead(pinZ7)==0) {return zone7;}
else {return currentZone;}
break;
default:
int firstDetection = -1;
while(firstDetection == -1)
{
if(digitalRead(pinZG)==0) {firstDetection = gareG;}
else if(digitalRead(pinZ1)==0) {firstDetection = zone1;}
else if(digitalRead(pinZ2)==0) {firstDetection = zone2;}
else if(digitalRead(pinZ3)==0) {firstDetection = zone3;}
else if(digitalRead(pinZC)==0) {firstDetection = gareC;}
else if(digitalRead(pinZ4)==0) {firstDetection = zone4;}
else if(digitalRead(pinZ5)==0) {firstDetection = zone5;}
else if(digitalRead(pinZ6)==0) {firstDetection = zone6;}
else if(digitalRead(pinZ7)==0) {firstDetection = zone7;}
else if(digitalRead(pinZD)==0) {firstDetection = gareD;}
}
return firstDetection;
}
}
/*choix du trajet suivant*/
int NextTrip(int CurrentTrip)
{
int newTrip;
//choix aléatoire d'un nombre
int choix = random(0,2);
//choix du nouveau trajet
if (CurrentTrip == GC || CurrentTrip == DC)
{
if (choix == 0) {newTrip = CG;}
else {newTrip = CD;}
}
else if (CurrentTrip == CG || CurrentTrip == DG)
{
if (choix == 0) {newTrip = GC;}
else {newTrip = GD;}
}
else if (CurrentTrip == CD || CurrentTrip == GD)
{
if (choix == 0) {newTrip = DC;}
else {newTrip = DG;}
}
if (sens[CurrentTrip]!=sens[newTrip])
{
/*attention il est impossible d'avoir les deux à HIGH en même temps*/
/* il faut inverser les deux*/
if (digitalRead(pinS1)==HIGH)
{
digitalWrite(pinS1,LOW);
digitalWrite(pinS2,HIGH);
}
else /*si ce n'est pas S1 à HIGH, c'est forcément S2*/
{
digitalWrite(pinS2,LOW);
digitalWrite(pinS1,HIGH);
}
}
return newTrip;
}
void setup() {
// initialisation des pins de l'arduino
pinMode(pinZG,INPUT_PULLUP);
pinMode(pinZ1,INPUT_PULLUP);
pinMode(pinZ2,INPUT_PULLUP);
pinMode(pinZ3,INPUT_PULLUP);
pinMode(pinZC,INPUT_PULLUP);
pinMode(pinZ4,INPUT_PULLUP);
pinMode(pinZ5,INPUT_PULLUP);
pinMode(pinZ6,INPUT_PULLUP);
pinMode(pinZ7,INPUT_PULLUP);
pinMode(pinZD,INPUT_PULLUP);
pinMode(pinACS,INPUT);
pinMode(pinEncP,INPUT_PULLUP);
//pinMode(pinEncS,INPUT); dans la définition de l'encodeur ligne 21
//pinMode(pinEncR,INPUT); dans la définition de l'encodeur ligne 21
pinMode(pinPWM,OUTPUT);
pinMode(pinS1,OUTPUT);
pinMode(pinS2,OUTPUT);
pinMode(pinSeed,INPUT);
randomSeed(getSeed()); /*pour l'aléatoire*/
endTrip = false;
currentTrip = GD;
digitalWrite(pinS2,HIGH);
digitalWrite(pinS1,LOW);
theSpeed = minSpeed;
//démarrage du train mais à PWM insuffisant pour faire avancer le train
analogWrite(pinPWM,80);
//détection de la zone où se situe le train
currentZone = WhereIsMyTrain(currentZone);
Serial.println(currentZone);
analogWrite(pinPWM,theSpeed);
}
void loop() {
if(endTrip == true) //le trajet est-il terminée
{
currentTrip = NextTrip(currentTrip); //choisir un nouveau trajet
endTrip = false;
delay(3000); //attendre trois secondes avant le redémarrage
}
currentZone = WhereIsMyTrain(currentZone);
switch (allures[currentTrip][currentZone])
{
case LENT:
if (theSpeed != minSpeed && isON == true) {theSpeed = minSpeed;}
break;
case RAPIDE:
if (theSpeed != maxSpeed && isON == true) {theSpeed = maxSpeed;}
break;
case ACC:
if ((theSpeed+stepSpeed)<=maxSpeed && isON == true) {theSpeed = theSpeed+stepSpeed;}
break;
case RAL:
if ((theSpeed-stepSpeed)>=minSpeed && isON == true) {theSpeed = theSpeed-stepSpeed;}
break;
case STOP: /*le trajet est terminé*/
theSpeed = 0;
endTrip = true;
}
analogWrite(pinPWM,theSpeed);
}