Je vais vous présenter comment j’ai imaginé puis réalisé ce projet.
Tout d’abord l’organisation de ma butte avec ce plan :
Afin de bien comprendre ce dessin, voici le lexique :
La première étape a été de créer le TCO et d’imaginer comment les leds allaient être allumées.
Deux choix : Leds fixes ou leds en chenillard.
Ce sera le deuxième choix qui sera le plus apprécié.
La commande des aiguillages se fera de façon séquentielle.
Afin de formaliser la commandes de tous les éléments, j’ai établi un tableau qui indique les conséquences des actions possibles :
Avant de commencer la programmation de l’Arduino, j’ai défini dans un tableau les « bornes » que je vais utiliser de l’Arduino. Ce tableau vous est présenté complet alors que les couleurs de conducteurs ont été mis au fur et à mesure de la réalisation :
Pour un aiguillage, une LED :
- le code « De » indique que l’aiguillage sera dévié,
- le code « Dr » indique que l’aiguillage sera droit.
- LED : si marqué « O » elle doit être allumée. Si une seule est allumée elle sera clignotante. S’il y en a plusieurs elles seront allumées sous forme « chenillard ».
Afin de ne pas faire d’erreur avec la commande des aiguillages j’ai effectué un test sur un aiguillage triple qui comporte deux électro-aimants :
La carte Arduino que j’ai choisi est la MEGA 2560 car j’avais besoin d’un nombre important d’entrées-sorties (au total : 36)
Pour le câblage des entrées et des sorties voici tous les schémas :
Les entrées : (sur les conseils de Guillaume)
Les sorties Leds :
Les sorties relais : feu (vert/rouge) et dételeur.
Les sorties aiguillages. Au départ je pensais utiliser des cartes relais. Suite aux conseils de Christian, j’ai décidé d’utiliser des amplificateurs ULN 2803.
Voici en pratique ce que cela donne :
Carte entrées sorties leds : Sur une base de circuit imprimé en bande voici le plan puis la réalisation :
Carte ampli pour aiguillage :
Pour finir le programme constitué de deux grandes parties :
La commande manuelle : Dans ce cas on actionne un des boutons poussoir. En premier lieu je commande d’abord tous les aiguillages (impulsion de 200 ms) de façon séquentielle (sans s’occuper de la position initiale de ceux-ci), puis la commande des leds du TCO.
La commande automatique : A l’aide des trois capteurs disposés sur la butte, l’Arduino commande le dételage automatique sur les 5 voies de triage et ce de façon aléatoire.
Merci à l'aide précieuse de Guillaume et de Christian.
Code : Tout sélectionner
/* PRG Butte de triage en cde manuelle et en automatique
Pierre GRAFTIEAUX Décembre 2013 */
/* Déclaration des toutes les variables */
// d'abord toutes les LEDS
const int lvg1 = 32; //led lvg2 en broche 32
const int lvt1 = 33; //led lvt1 en broche 33
const int lvg2 = 34; //led lvg2 en broche 34
const int lvt5g2 = 35; //led lvt5g2 en broche 35
const int ldet = 36; //led ldet en broche 36
const int lvt234 = 37; //led ldet en broche 37
const int lvt2 = 38; //led lvt2 en broche 38
const int lvt3 = 39; //led lvt3 en broche 39
const int lvt4 = 40; //led lvt4 en broche 40
const int lvt5 = 41; //led lvt5 en broche 38
const int lclig = 20; // led clignotante en broche 20
const int feu = 17; // feu de signalisation vert/rouge en automatique
//Ensuite les récepteurs à alimenter
const int det = 21; // dételeur en broche 21
const int a31de = 42; //Aiguillage A31 dévié en broche 42
const int a31dr = 43; //Aiguillage A31 droit en broche 43
const int a32de = 44; //Aiguillage A31 dévié en broche 44
const int a32dr = 45; //Aiguillage A31 droit en broche 45
const int a33de = 46; //Aiguillage A31 dévié en broche 46
const int a33dr = 47; //Aiguillage A31 droit en broche 47
const int a34de = 48; //Aiguillage A31 dévié en broche 48
const int a34dr = 49; //Aiguillage A31 droit en broche 49
const int a35de = 50; //Aiguillage A31 dévié en broche 50
const int a35dr = 51; //Aiguillage A31 droit en broche 51
const int a36de = 52; //Aiguillage A31 dévié en broche 52
const int a36dr = 53; //Aiguillage A31 droit en broche 53
// puis tous les boutons poussoirs
const int bvg1 = 22; // BP bvg1 en broche 22
const int bvt1 = 23; // BP bvt1 en broche 23
const int bvt2 = 24; // BP bvt2 en broche 24
const int bvt3 = 25; // BP bvt3 en broche 25
const int bvt4 = 26; // BP bvt4 en broche 26
const int bvt5 = 27; // BP bvt5 en broche 25
const int bvg2 = 28; // BP bvg2 en broche 28
const int bdet = 29; // BP bdet en broche 29
const int aqml = 30; // commutateur AQML en broche 30
const int cdet1 = 31; // capteur dételage1 en broche 31
const int cdet2 = 19; // capteur dételage2 en broche 19
const int cdet3 = 18; // capteur wagon trié
// enfin les variables internes nécessaires à la gestion des variables
boolean b1; // état de bvg1
boolean b2; // état de bvt1
boolean b3; // état de bvt2
boolean b4; // état de bvt3
boolean b5; // état de bvt4
boolean b6; // état de bvt5
boolean b7; // état de bvg2
boolean b8; // état de bdet
boolean b9; // état de aqml b9 = 0 en aq
boolean b10; // état du capteur dételage cdet1
boolean b11; // état du capteur dételage cdet2
boolean b12; // état du capteur cdet3 wagon trié
byte broche; // n° broche d'un aiguillage
byte mbp; // mémoire du bP actionné
unsigned long temps; // variable temps pour le clignotement
boolean i; // pour impulsion aiguillage
boolean j; // pour impulsion aiguillage
boolean k; // pour impulsion aiguillage
boolean l; // pour impulsion aiguillage
boolean m; // pour impulsion aiguillage
boolean n; // pour impulsion aiguillage
boolean o; // pour impulsion aiguillage
boolean p; // pour impulsion aiguillage
boolean r; // pour génération nbre aléatoire
boolean s; // pour séquence déeleur une fois en automatqiue
boolean vtri; // variable pour nb aléatoire entre 1 et 5
/* configuration des entrées et sorties */
void setup()
{
// définition des sorties LEDS
pinMode(lvg1, OUTPUT);
pinMode(lvt1, OUTPUT);
pinMode(lvg2, OUTPUT);
pinMode(lvt5g2, OUTPUT);
pinMode(ldet, OUTPUT);
pinMode(lvt234, OUTPUT);
pinMode(lvt2, OUTPUT);
pinMode(lvt3, OUTPUT);
pinMode(lvt4, OUTPUT);
pinMode(lvt5, OUTPUT);
pinMode(lclig, OUTPUT);
pinMode(feu, OUTPUT);
// Définition des sorties actionneurs dételeur aiguillages
pinMode(det, OUTPUT);
pinMode(a31de, OUTPUT);
pinMode(a31dr, OUTPUT);
pinMode(a32de, OUTPUT);
pinMode(a32dr, OUTPUT);
pinMode(a33de, OUTPUT);
pinMode(a33dr, OUTPUT);
pinMode(a34de, OUTPUT);
pinMode(a34dr, OUTPUT);
pinMode(a35de, OUTPUT);
pinMode(a35dr, OUTPUT);
pinMode(a36de, OUTPUT);
pinMode(a36dr, OUTPUT);
// définition des entrées
pinMode(bvg1, INPUT);
pinMode(bvt1, INPUT);
pinMode(bvt2, INPUT);
pinMode(bvt3, INPUT);
pinMode(bvt4, INPUT);
pinMode(bvt5, INPUT);
pinMode(bvg2, INPUT);
pinMode(bdet, INPUT);
pinMode(aqml, INPUT);
pinMode(cdet1, INPUT);
pinMode(cdet2, INPUT);
pinMode(cdet3, INPUT);
//Toutes les leds seront éteintes au départ ou lors d'un reset
led0();
b1=b2=b3=b4=b5=b6=b7=b8=b9=b10=b11=1;
b12=1;
r=s=0;
// cde pour pouvoir avoir une génération aléatoire avec random
randomSeed(analogRead(0)); // lit la "valeur" de l'entre analogique 0 non utilisée
}
/* début du programme */
void loop()
{
// cde aiguillages et leds en "manuel"
b9 = digitalRead(aqml);
if(b9 == 1)
{
//test action des BP et mise en mémoire dans mbp
b1 = digitalRead(bvg1);
b2 = digitalRead(bvt1);
b3 = digitalRead(bvt2);
b4 = digitalRead(bvt3);
b5 = digitalRead(bvt4);
b6 = digitalRead(bvt5);
b7 = digitalRead(bvg2);
b8 = digitalRead(bdet);
b10 = digitalRead(cdet1);
b11 = digitalRead(cdet2);
// mise en mémoire de l'action sur les bp dans, la mémoire mbp
if(b1 == 0)
{mbp = 1;}
if(b2 == 0)
{mbp = 2;}
if(b3 == 0)
{mbp = 3;}
if(b4 == 0)
{mbp = 4;}
if(b5 == 0)
{mbp = 5;}
if(b6 == 0)
{mbp = 6;}
if(b7 == 0)
{mbp = 7;}
// cde des aiguillages par impulsion durée réglée dans la fonction cde_aig(broche)
if(mbp == 1 && j<1) // cde aiguillage a31dr
{
raz_var(); // remet à 0 toutes les variables utilisées pour faire impulsion
j++; // incrémente j pour ne faire qu'une impulsion sur l'aiguillage
cde_aig(43);
}
// cde aiguillage a31de puis a32de puis a33dr
if(mbp == 2 && i<1)
{
raz_var();
i++;
cde_aig(42);
cde_aig(44);
cde_aig(47);
}
// cde aiguillage a31de puis a32dr puis a33dr puis a34de puis a35dr
if(mbp == 3 && k<1)
{
raz_var();
k++;
cde_aig(42);
cde_aig(45);
cde_aig(47);
cde_aig(48);
cde_aig(51);
}
// cde aiguillage a31de puis a32dr puis a33dr puis a34dr puis a35dr
if(mbp == 4 && l<1)
{
raz_var();
l++;
cde_aig(42);
cde_aig(45);
cde_aig(47);
cde_aig(49);
cde_aig(51);
}
// cde aiguillage a31de puis a32dr puis a33dr puis a34dr puis a35de
if(mbp == 5 && m<1)
{
raz_var();
m++;
cde_aig(42);
cde_aig(45);
cde_aig(47);
cde_aig(49);
cde_aig(50);
}
// cde aiguillage a31de puis a32dr puis a33de puis a36de
if(mbp == 6 && o<1)
{
raz_var();
o++;
cde_aig(42);
cde_aig(45);
cde_aig(46);
cde_aig(52);
}
// cde aiguillage a31de puis a32dr puis a33de puis a36dr
if(mbp == 7 && p<1)
{
raz_var();
p++;
cde_aig(42);
cde_aig(45);
cde_aig(46);
cde_aig(53);
}
// cde dételeur en manuel
if(b8 == 0)
{digitalWrite(21, 1);}
else
{digitalWrite(21, 0);}
// cde de la led clignotante pour indiquer que l'on peu dételer
if(b10 == 1 && b11 == 0)
{digitalWrite(20,1);}
else
{digitalWrite(20,0);}
switch(mbp)
{
case 1: // action à faire lors de l'appui sur bvg1
led0();
if((millis() - temps) > 250)
{digitalWrite(lvg1, 1);}
if((millis() - temps) > 500)
{temps = millis();}
break;
case 2: // action à faire lors de l'appui sur bvt1
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt1, 1);}
if((millis() - temps) > 750)
{temps = millis();}
break;
case 3: //action à faire lors de l'appui sur bvt2
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt234, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt2, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
case 4: // action à faire lors de l'appui sur bvt3
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt234, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt3, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
case 5: // action à faire lors de l'appui sur bvt4
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt234, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt4, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
case 6: // action à faire lors de l'appui sur bvt5
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt5g2, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt5, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
case 7: // action à faire lors de l'appui sur bvg2
led0(); // appel fonction éteindre toutes les leds
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt5g2, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvg2, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
}
}
// cde en automatique
if(b9 == 0)
{
b10 = digitalRead(cdet1);
b11 = digitalRead(cdet2);
b12 = digitalRead(cdet3);
// génère un nombre entre 1 et 5 pour définir l'une des voies de tri
if (b10 == 0 && r<1)
{
r++;
vtri = random(1,6);
cde_aig(42); // met l'aiguillage A31 dévié vers tri
}
if(b12 == 0)
{r=s=0;}
// cde aiguillage a32de puis a33dr
if (vtri == 1 && b10 == 0 && i<1)
{
raz_var();
i++;
cde_aig(44);
cde_aig(47);
}
// cde aiguillage a32dr puis a33dr puis a34de puis a35dr
if(vtri == 2 && b10 == 0 && k<1)
{
raz_var();
k++;
cde_aig(45);
cde_aig(47);
cde_aig(48);
cde_aig(51);
}
// cde aiguillage a32dr puis a33dr puis a34dr puis a35dr
if(vtri == 3 && b10 == 0 && l<1)
{
raz_var();
l++;
cde_aig(45);
cde_aig(47);
cde_aig(49);
cde_aig(51);
}
// cde aiguillage a32dr puis a33dr puis a34dr puis a35de
if(vtri == 4 && b10 == 0 && m<1)
{
raz_var();
m++;
cde_aig(45);
cde_aig(47);
cde_aig(49);
cde_aig(50);
}
// cde aiguillage a32dr puis a33de puis a36de
if(vtri == 5 && b10 == 0 && o<1)
{
raz_var();
o++;
cde_aig(45);
cde_aig(46);
cde_aig(52);
}
// cde du dételeur
if(b10 == 1 && b11 == 0 && s<1)
{
s++;
{digitalWrite(21, 1);}
delay(500);
{digitalWrite(21, 0);}
delay(200);
{digitalWrite(21, 1);}
delay(500);
{digitalWrite(21, 0);}
}
// cde du feu au vert
if (s == 1)
{
digitalWrite(feu, 1);}
else
{digitalWrite(feu, 0);}
switch(vtri)
{
case 1: // action à faire comme lors de l'appui sur bvt1
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt1, 1);}
if((millis() - temps) > 750)
{temps = millis();}
break;
case 2: //action à faire comme lors de l'appui sur bvt2
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt234, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt2, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
case 3: // action à faire comme lors de l'appui sur bvt3
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt234, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt3, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
case 4: // action à faire comme lors de l'appui sur bvt4
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt234, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt4, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
case 5: // action à faire comme lors de l'appui sur bvt5
led0();
if((millis() - temps) > 250)
{digitalWrite(ldet, 1);}
if((millis() - temps) > 500)
{digitalWrite(lvt5g2, 1);}
if((millis() - temps) > 750)
{digitalWrite(lvt5, 1);}
if((millis() - temps) > 1000)
{temps = millis();}
break;
}
}
}
// création des fonctions
void led0() // fonction eteindre toutes les leds
{
digitalWrite(lvg1, 0);
digitalWrite(lvt1, 0);
digitalWrite(lvg2, 0);
digitalWrite(lvt5g2, 0);
digitalWrite(ldet, 0);
digitalWrite(lvt234, 0);
digitalWrite(lvt2, 0);
digitalWrite(lvt3, 0);
digitalWrite(lvt4, 0);
digitalWrite(lvt5, 0);
}
void cde_aig(int broche) // cde d'aiguillage par le code broche
{
digitalWrite(broche, 1);
delay(200);
digitalWrite(broche, 0);
}
void raz_var() // raz des variables pour cde aiguillage impulsion
{
i=j=k=l=m=n=o=p=0;
}