/*attiny84 cde 2 aiguillages KATO
11/12/2023
Dominique Hudry
liens: https://electroniqueamateur.blogspot.com/2019/06/controler-plusieurs-leds-avec-arduino.html
https://wokwi.com/projects/383829237167637505
Commande de deux aigillages KATO par l'appui de BP
Une impulsion unique et de durée fixe est envoyé à un étage de puissance (L293D double pont en H)
qui alimente la bobine de chaque aiguillage en modifiant la polarité .
La position de chaque aiguillage est indiquée par des leds, le nombre limité des pins imposant le charlieplexing.
Brochage ATtiny84
VCC=|1 U 14|= GND
BrocheC <-->10 =|2 13|= 0<-- BPdroit1--GND
BrocheB <-->9 =|3 12|= 1<-- BPdevie1--GND
Reset =|4 11|= 2<-- BPdroit2--GND
BrocheA <-->8 =|5 10|= 3<-- BPdevie2--GND
CdeInput4 <--7 =|6 9|= 4--> CdeInput1
CdeInput3 <--6 =|7 8|= 5--> CdeInput2
Brochage L293D
+5V--Enable1 =|1 U 16|= +5V
CdeInput1--Input1 =|2 15|= Input4--CdeInput4
Output1 =|3 14|= Output4
GND =|4 13|= GND
GND =|5 12|= GND
Output2 =|6 11|= Output3
CdeInput2--Input2 =|7 10|= Input3--CdeInput3
+12V--VS =|8 9|= Enable2--+5V
E1 Input1 Input2 Output1 Output2 E2 Input3 Input4 Output3 Output4
1 0 0 pas de ddp 1 0 0 pas de ddp
1 0 + - 1 0 + -
0 1 - + 0 1 - +
1 1 pas de ddp 1 1 pas de ddp
la bobine de l'aiguiilage1 se branche entre Output1 (fil rouge) et Output2 (fil noir)
si impulsion positive sur Input1 alors Output1 est au + et Output2 est au -
si impulsion positive sur Input2 alors Output1 est au - et Output2 est au +
la bobine de l'aiguiilage2 se branche entre Output3 (fil rouge) et Output4 (fil noir)
si impulsion positive sur Input3 alors Output3 est au + et Output4 est au -
si impulsion positive sur Input4 alors Output3 est au - et Output4 est au +
*/
const byte BPdroit1 = 12; // branchement du BP pour commander la position Droit1
const byte BPdevie1 = 11; // branchement du BP pour commander la position Dévié1
const byte BPdroit2 = 2; // branchement du BP pour commander la position Droit2
const byte BPdevie2 = 3; // branchement du BP pour commander la position Dévié2
const byte CdeInput1 = 4; // liaison avec Input1 du L293D
const byte CdeInput2 = 5; // liaison avec Input2 du L293D
const byte CdeInput3 = 6; // liaison avec Input3 du L293D
const byte CdeInput4 = 7; // liaison avec Input4 du L293D
const byte BrocheA = 8; // cde des leds en charlieplexing
const byte BrocheB = 9; // cde des leds en charlieplexing
const byte BrocheC = 10; // cde des leds en charlieplexing
const byte DureeImpulsion = 20; // durée en ms des impulsions envoyées par les CdeInput
bool etatLeds[] = {0, 0, 0, 0}; // état des 4 leds de position, au démarrage tout est éteint
bool etatBPdroit1; // BP relaché: HIGH, BP appuyé: LOW
bool etatBPdevie1; // BP relaché: HIGH, BP appuyé: LOW
bool etatBPdroit2; // BP relaché: HIGH, BP appuyé: LOW
bool etatBPdevie2; // BP relaché: HIGH, BP appuyé: LOW
bool validationBPdroit1; // permet la prise en compte ou non d'un appui sur BPdroit1
bool validationBPdevie1; // permet la prise en compte ou non d'un appui sur BPdevie1
bool validationBPdroit2; // permet la prise en compte ou non d'un appui sur BPdroit2
bool validationBPdevie2; // permet la prise en compte ou non d'un appui sur BPdevie2
void setup() {
pinMode(BPdroit1, INPUT_PULLUP); // configuration des pins en entrée
pinMode(BPdevie1, INPUT_PULLUP);
pinMode(BPdroit2, INPUT_PULLUP);
pinMode(BPdevie2, INPUT_PULLUP);
pinMode(CdeInput1, OUTPUT); // configuration des pins en sortie
pinMode(CdeInput2, OUTPUT);
pinMode(CdeInput3, OUTPUT);
pinMode(CdeInput4, OUTPUT);
digitalWrite(CdeInput1, LOW); // à la mise sous tension toutes les commandes sont au niveau LOW
digitalWrite(CdeInput2, LOW);
digitalWrite(CdeInput3, LOW);
digitalWrite(CdeInput4, LOW);
validationBPdroit1 = true; // permet la prise en compte de n'importe lequel des BP
validationBPdevie1 = true;
validationBPdroit2 = true;
validationBPdevie2 = true;
efface_tout(); // les leds de position sont toutes éteintes
} // fin setup
void loop() {
// gestion de l'allumage des leds de position des deux aiguillages
for (byte i = 0; i < 4 ; i++) { // on cherche quelles leds doivent être allumées
if (etatLeds[i] == 1) {
reglage_led(i + 1); // on régle les paramètres pour chaque led devant être allumée
} // fin if
else {
efface_tout(); // sinon on les éteint toutes
} // fin else
} // fin for
// gestion du BP pour positionnement de l'aiguillage1 en position Droit
etatBPdroit1 = digitalRead (BPdroit1); // lecture de l'état du BPdroit1
if (etatBPdroit1 == LOW && validationBPdroit1 == true) { // si conditions pour un déclenchement
digitalWrite(CdeInput1, HIGH); // impulsion envoyée sur input1 du L293D
delay(DureeImpulsion);
digitalWrite(CdeInput1, LOW);
etatLeds[0] = 1; // la led1 Aiguillage1 Droit s'allume
etatLeds[1] = 0; // la led2 Aiguillage1 Dévié s'éteint
validationBPdroit1 = false; // les déclenchements par BPdirect sont bloqués
validationBPdevie1 = true; // seule une action sur BPdevie est autorisée
} // fin if
// gestion du BP pour positionnement de l'aiguillage1 en position Dévié
etatBPdevie1 = digitalRead (BPdevie1); // lecture de l'état du BPdevie
if (etatBPdevie1 == LOW && validationBPdevie1 == true) { // si conditions pour un déclenchement
digitalWrite(CdeInput2, HIGH); // impulsion envoyée sur input2 du L293D
delay(DureeImpulsion);
digitalWrite(CdeInput2, LOW);
etatLeds[0] = 0; // la led1 Aiguillage1 Droit s'éteint
etatLeds[1] = 1; // la led2 Aiguillage1 Dévié s'allume
validationBPdevie1 = false; // les déclenchements par BPdevie sont bloqués
validationBPdroit1 = true; // seule une action sur BPdroit est autorisée
} // fin if
// gestion du BP pour positionnement de l'aiguillage2 en position Droit
etatBPdroit2 = digitalRead (BPdroit2); // lecture de l'état du BPdroit2
if (etatBPdroit2 == LOW && validationBPdroit2 == true) { // si conditions pour un déclenchement
digitalWrite(CdeInput3, HIGH); // impulsion envoyée sur input3 du L293D
delay(DureeImpulsion);
digitalWrite(CdeInput3, LOW);
etatLeds[2] = 1; // la led3 Aiguillage2 Droit s'allume
etatLeds[3] = 0; // la led4 Aiguillage2 Dévié s'éteint
validationBPdroit2 = false; // les déclenchements par BPdroit2 sont bloqués
validationBPdevie2 = true; // seule une action sur BPdevie2 est autorisée
} // fin if
// gestion du BP pour positionnement de l'aiguillage2 en position Dévié
etatBPdevie2 = digitalRead (BPdevie2); // lecture de l'état du BPdevie2
if (etatBPdevie2 == LOW && validationBPdevie2 == true) { // si conditions pour un déclenchement
digitalWrite(CdeInput4, HIGH); // impulsion envoyée sur input4 du L293D
delay(DureeImpulsion);
digitalWrite(CdeInput4, LOW);
etatLeds[3] = 1; // la led4 Aiguillage2 Dévié s'allume
etatLeds[2] = 0; // la led3 Aiguillage2 Droit s'éteint
validationBPdevie2 = false; // les déclenchements par BPdevie2 sont bloqués
validationBPdroit2 = true; // seule une action sur BPdroit2 est autorisée
} // fin if
} // fin loop
void efface_tout() {
pinMode(BrocheA, INPUT); // on met les 3 broches de commande en haute impédance
pinMode(BrocheB, INPUT);
pinMode(BrocheC, INPUT);
} // fin efface_tout
void reglage_led(byte numeroLed) { // pour chaque led devant s'allumer on précise uniquement les broches impliquées
switch (numeroLed) {
case 1: // led1 Aiguillage1 Droit
reglage_broches(BrocheA, BrocheB); // A+ B-
break;
case 2: // led2 Aiguillage1 Dévié
reglage_broches(BrocheB, BrocheA); // B+ A-
break;
case 3: // led3 Aiguillage2 Droit
reglage_broches(BrocheB, BrocheC); // B+ C-
break;
case 4: // led4 Aiguillage2 Dévié
reglage_broches(BrocheC, BrocheB); // C+ B-
break;
default:
break;
} // fin switch case
} // fin reglage_led
void reglage_broches(byte anode, byte cathode) { // on fixe le niveau des broches impliquées
efface_tout(); // on éteint les leds, donc il restera systématiquement une broche en haute impédance
pinMode(anode, OUTPUT); // la broche qui envoie du +5V
digitalWrite(anode, HIGH);
pinMode(cathode, OUTPUT);// la broche qui est à la masse
digitalWrite(cathode, LOW);
} // fin reglage_broches