LOCODUINO
Parlons Arduino => Shields et Modules => Discussion démarrée par: trimarco232 le juin 24, 2022, 10:35:48 am
-
suite à la demande de Pierrre sur https://www.locoduino.org/spip.php?article161#forum6190 (https://www.locoduino.org/spip.php?article161#forum6190)
/*
Decoder for traffic light with three or two /// or 4 leds on ARDUINO NANO
by default the red leds are switched on
pin 2 receives DCC interrupts
TRAFFIC LIGHT WITH THREE leds (GREEN, RED, YELLOW)
5 decoders of traffic lights with three leds on Arduino NANO/UNO
the leds are controlled by pins 3 to A3 by triplet
traffic light 1 : 3,4,5
traffic light 2 : 6,7,8
traffic light 3 : 9,10,11
traffic light 4 : 12,13,A0
traffic light 5 : A1,A2,A3
two addresses by traffic light
even addresses for green and red lights
odd addresses for yellow light
/// TRAFFIC LIGHT WITH 4 leds (green, red, yellow, carre))
4 decoders of traffic lights with 4 leds on Arduino NANO/UNO
the leds are controlled by pins 3 to A4 by quadruplets
traffic light 1 : 3,4,5,6
traffic light 2 : 7,8,9,10
traffic light 3 : 11,12,13,A0
traffic light 4 : A1,A2,A3,A4
two addresses by traffic light
even addresses for green and red lights
/// odd addresses for yellow and carre indications
TRAFFIC LIGHT WITH TWO leds (GREEN, RED)
8 decoders of traffic lights with two leds on Arduino NANO/UNO
the leds are controlled by pins 3 to A4 by pair
traffic light 1 : 3,4
traffic light 2 : 5,6
traffic light 3 : 7,8
traffic light 4 : 9,10
traffic light 5 : 11,12
traffic light 6 : 13,A0
traffic light 7 : A1,A2
traffic light 8 : A3,A4
one address by traffic light
CONFIGURATION
MODE : determined by the common of the led, LOW if common = HIGH, HIGH if common = LOW
FIRST_ID_DCC : DCC address of the first traffic light
NB_TRAFFIC_LIGHT : determined by the kind of traffic light, BICOLOR for two leds, TRICOLOR for three leds
*/
/// modifs / ajouts pour 4 feux
//// dégobage pour modifs pour 4 feux : supprimer la ligne
/***************************************************************************************
CONFIGURATION SETTING
****************************************************************************************/
#define CONSOLE // output console, comment this line after checking the soft
#define MODE LOW // LOW or HIGH
#define FIRST_ID_DCC 90 // first DCC address, DCC_CODE
#define NB_TRAFFIC_LIGHT FOURCOLOR // TRICOLOR or BICOLOR /// ou FOURCOLOR
/**********************************************************************************
DON'T CHANGE THE FOLLOWING
*********************************************************************************/
/******************************************************************************
INTERNAL PARAMETERS
********************************************************************************/
// DCC
#include "DCC_Decoder.h" // Minabay library /// "DCC_Decoder.c" must be present too in the folder
#define kDCC_INTERRUPT 0 // pin 2 receives DCC interrupts
int previous_address = 0; // avoids multiple DCC addresses
int previous_position = 2; // avoids multiple DCC orders
volatile boolean update_light; // set if an update should be processed after DCC control
// traffic light
#define BICOLOR 8 // 8 traffic lights with two leds
#define TRICOLOR 5 // 5 traffic lights with three leds
#define FOURCOLOR 4 /// 4 traffic lights with 4 leds
#define FIRST_PIN 3 // pin of the first traffic light
#define GREEN 0 // address DCC/0
#define RED 1 // address DCC/1
#define YELLOW 2 // address DCC+1/0
#define CARRE 3 /// address DCC+1/1
// traffic light definition
struct light {
int address; // its DCC address
int current_position; // green / red / yellow /// carre
int green; // pin of the green led
int red; // pin of the red led
int yellow; // pin of the yellow led
int carre; /// pin of the carre led
boolean activation_request; // request of activation
};
light traffic_light[NB_TRAFFIC_LIGHT]; // the set of traffic light
/********************************************************************
method called if a request is made by the DCC
*******************************************************************/
void activation_traffic_light() {
for (int i = 0; i < NB_TRAFFIC_LIGHT; i++) // for all traffic lights
{
if (traffic_light[i].activation_request == true) // if the traffic_light is waiting for activation
{
switch (traffic_light[i].current_position) // we look the current position
{
case GREEN : { /// indication GREEN
digitalWrite(traffic_light[i].green, MODE); // switch on green
digitalWrite(traffic_light[i].red, !MODE); // switch off red
if ( NB_TRAFFIC_LIGHT == TRICOLOR || NB_TRAFFIC_LIGHT == FOURCOLOR) {
digitalWrite(traffic_light[i].yellow, !MODE); // switch off yellow
}
if ( NB_TRAFFIC_LIGHT == FOURCOLOR) { ///
digitalWrite(traffic_light[i].carre, !MODE); /// switch off carre
}
/**/#ifdef CONSOLE
Serial.print("active -> signal "); Serial.print(i); Serial.println(" : green led");
/**/#endif
break;
}
case RED : { /// indication RED
digitalWrite(traffic_light[i].green, !MODE); // switch off green
digitalWrite(traffic_light[i].red, MODE); // switch on red /// incomplet ?
if ( NB_TRAFFIC_LIGHT == TRICOLOR || NB_TRAFFIC_LIGHT == FOURCOLOR) {
digitalWrite(traffic_light[i].yellow, !MODE); // switch off yellow
}
if ( NB_TRAFFIC_LIGHT == FOURCOLOR) { ///
digitalWrite(traffic_light[i].carre, !MODE); /// switch off carre
}
/**/#ifdef CONSOLE
Serial.print("active -> signal "); Serial.print(i); Serial.println(" : red led");
/**/#endif
break;
}
case YELLOW : { /// indication YELLOW
digitalWrite(traffic_light[i].green, !MODE); // switch off green
digitalWrite(traffic_light[i].red, !MODE); // switch off red
digitalWrite(traffic_light[i].yellow, MODE); // switch on yellow
if ( NB_TRAFFIC_LIGHT == FOURCOLOR) { ///
digitalWrite(traffic_light[i].carre, !MODE); /// switch off carre
}
/**/#ifdef CONSOLE
Serial.print("active -> signal "); Serial.print(i); Serial.println(" : yellow led");
/**/#endif
break;
}
case CARRE : { /// indication CARRE
digitalWrite(traffic_light[i].green, !MODE); // switch off green
digitalWrite(traffic_light[i].red, MODE); /// switch on red // incomplet ?
digitalWrite(traffic_light[i].yellow, !MODE); // switch off yellow
digitalWrite(traffic_light[i].carre, MODE); /// switch on carre
/**/#ifdef CONSOLE
Serial.print("active -> signal "); Serial.print(i); Serial.println(" : carre + red led");
/**/#endif
break;
}
}
}
traffic_light[i].activation_request = false; // the traffic light is updated
}
update_light = false; // all updates are made
}
/*************************************************************************************
DCC method
***********************************************************************************/
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
address -= 1; address *= 4; address += 1; address += (data & 0x06) >> 1; // DCC address decoding
int led = (data & 0x01) ? GREEN : RED; // DCC/0 or DCC/1
int traffic_light_index = address; // index of a traffic light
int color = led; // the color of the led
boolean activation = false;
if ((address != previous_address) || ((led != previous_position) && (address == previous_address))) { // if we change the address or the led
switch (NB_TRAFFIC_LIGHT) {
case BICOLOR : { // if the address is in our range for traffic light with two leds
if ((address >= FIRST_ID_DCC) && (address < FIRST_ID_DCC + NB_TRAFFIC_LIGHT)) {
traffic_light_index = address - FIRST_ID_DCC; // index of the traffic light
activation = true;
}
break;
}
case TRICOLOR : { // if the address is in our range for traffic light with three leds
if ((address >= FIRST_ID_DCC) && (address < FIRST_ID_DCC + (2 * NB_TRAFFIC_LIGHT))) {
if (address % 2 != 0) {
traffic_light_index = address - 1; // if odd address => yellow led
color = YELLOW;
}
traffic_light_index = (traffic_light_index - FIRST_ID_DCC) / 2; // index of the traffic light
activation = true;
}
break;
}
case FOURCOLOR : { /// if the address is in our range for traffic light with 4 leds
if ((address >= FIRST_ID_DCC) && (address < FIRST_ID_DCC + (2 * NB_TRAFFIC_LIGHT))) {
if (address % 2 != 0) {
traffic_light_index = address - 1; // if odd address => yellow led
if (data & 0x01) color = CARRE; else color = YELLOW; /// en fonction du poids faible
}
traffic_light_index = (traffic_light_index - FIRST_ID_DCC) / 2; // index of the traffic light
activation = true;
/**/#ifdef CONSOLE
Serial.print("s"); Serial.print(traffic_light_index); Serial.print(" a"); Serial.print(address); Serial.print("/"); Serial.print(data & 0x01); Serial.print(" ");
/**/#endif
}
break;
}
}
traffic_light[traffic_light_index].activation_request = activation; // activation is requested
traffic_light[traffic_light_index].current_position = color; // state is requested (color of the led)
update_light = activation; // traffic light update is requested
}
previous_address = address; previous_position = led; // the current activation is saved
}
/**********************************************************************************************
setup
******************************************************************************************/
void setup() {
#ifdef CONSOLE
Serial.begin(115200);
#endif
delay(1500); /// compatible debogage promicro
int pin_jump = 0; // a jump for traffic light pins
int traffic_light_jump = 0; // a jump for traffic light number
for (int i = 0; i < NB_TRAFFIC_LIGHT; i++) { // for all the traffic lights
traffic_light[i].activation_request = false; // no activation request
traffic_light[i].green = pin_jump + FIRST_PIN; // pin number of the green led
pinMode(traffic_light[i].green, OUTPUT); // green led in output(ID DCC/0)
digitalWrite(traffic_light[i].green, !MODE); // green led switch off
traffic_light[i].red = 1 + pin_jump + FIRST_PIN; // pin number of the red led
pinMode(traffic_light[i].red, OUTPUT); // red led in output (ID DCC/1)
digitalWrite(traffic_light[i].red, MODE); // red led switch on
if (NB_TRAFFIC_LIGHT == TRICOLOR || NB_TRAFFIC_LIGHT == FOURCOLOR ) { // if 3 leds /// or 4 leds
traffic_light[i].address = traffic_light_jump + FIRST_ID_DCC + i; // its DCC ID
traffic_light[i].yellow = 2 + pin_jump + FIRST_PIN; // pin number of the yellow led
pinMode(traffic_light[i].yellow, OUTPUT); // yellow led in output (ID DCC+1/0)
digitalWrite(traffic_light[i].yellow, !MODE); // yellow led switch off
traffic_light_jump++; // the following traffic light
pin_jump += 3; // the following pin for three leds
if (NB_TRAFFIC_LIGHT == FOURCOLOR) { /// if 4 leds
traffic_light[i].carre = pin_jump + FIRST_PIN;
pinMode(traffic_light[i].carre, OUTPUT); // carre led in output (ID DCC+1/1)
digitalWrite(traffic_light[i].carre, MODE); // carre led switch on
pin_jump += 1; /// the following pin for 4 leds
}
}
else { // if two leds
traffic_light[i].address = FIRST_ID_DCC + i; // its DCC ID
pin_jump += 2; // the following pin for two leds
}
}
DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true); // instanciate the DCC
DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT ); // its IT
update_light = false; // no update
#ifdef CONSOLE
//// Serial.begin(115200);
Serial.println(""); Serial.println(""); Serial.println(""); ///
for (int i = 0; i < NB_TRAFFIC_LIGHT; i++) {
Serial.print("traffic light "); Serial.println(i);
Serial.print("\t green led on pin : "); Serial.print(traffic_light[i].green); Serial.print(" , DCC address : "); Serial.print(traffic_light[i].address); Serial.println("/0");
Serial.print("\t red led on pin : "); Serial.print(traffic_light[i].red); Serial.print(" , DCC address : "); Serial.print(traffic_light[i].address); Serial.println("/1");
if (NB_TRAFFIC_LIGHT == TRICOLOR) {
Serial.print("\t yellow led on pin : "); Serial.print(traffic_light[i].yellow); Serial.print(" , DCC address : "); Serial.print(traffic_light[i].address + 1); Serial.println("/0");
}
else if (NB_TRAFFIC_LIGHT == FOURCOLOR) { ///
Serial.print("\t yellow led on pin : "); Serial.print(traffic_light[i].yellow); Serial.print(" , DCC address : "); Serial.print(traffic_light[i].address + 1); Serial.println("/0");
Serial.print("\t carre led on pin : "); Serial.print(traffic_light[i].carre); Serial.print(" , DCC address : "); Serial.print(traffic_light[i].address + 1); Serial.println("/1");
}
}
#endif
}
/*************************************************************************
loop
************************************************************************/
void loop() {
DCC.loop(); // Is there a DCC command ?
delay(2000) ; ////
BasicAccDecoderPacket_Handler(24, 1, 2); ////
if (update_light) {
activation_traffic_light(); // if yes, activation of traffic lights
}
delay(2000) ; ////
BasicAccDecoderPacket_Handler(24, 1, 5); ////
if (update_light) { ////
activation_traffic_light(); // if yes, activation of traffic lights ////
} ////
}
édits : regarder svp. la date du dernier Modifié pour s'assurer d'avoir la dernière version
-
Bonjour,
parfait, testé sur les premières adresses sans problème.
-
Bonjour msport,
merci pour le test, car j'ai dû me contenter de faire des simulations
-
Bonjour à tous,
Un très grand merci pour ce travail.
Pour ma part j'ai dessiné la carte imprimé et j'espère la câbler d'ici mercredi prochain pour faire l'essai au club.
Je vous tiendrais informé dès que j'aurais fait ces essais (centrale digikeys et logiciel Trancontroller Gold).
Arduinotement vôtre.
Pierre
-
Bonjour à tous,
La carte est câblée. Mise sous tension :
Toutes les leds red sont allumées, les leds "carré" sont allumées mais la sortie A0 "clignote".
En mettant la console il y a en effet une commande alternée red puis carre + red. Donc cela produit le clignotement de la led carre.
J'avais fait un essai la semaine dernière et cela faisait cela au club même quand le DCC était alimenté et avec la manette ROCO impossible de commander les feux. Mais je n'avais pas l'ordinateur portable et je ne pouvais pas voir ce qui se passait.
Je ferais un nouvel essai demain AM.
Je ne comprends donc pas ce qui se passe. Je n'ai pas mis de condensateur sur les entrées de l'optocoupleur. Sur la version 3 leds non plus et cela fonctionne donc ?
Je me suis dit que mon circuit avait un PB. J'ai donc fait un câblage sur bredboard et cela produit le même effet (sans signal DCC). Pourtant en regardant les photos de MSPORT cela fonctionne !
Je vous donne des nouvelles jeudi après essai au club demain AM.
Arduinotement vôtre
Pierre
-
Bonjour à tous,
Voici les nouvelles :
Il semblerait que les commandes DCC ne sont pas effectives :
1- Supposition 1 : L'optocoupleur a un PB. J'ai donc pris l'optocoupleur de la carte 3 leds et je l'ai mis sur la carte 4 leds. Même effet.
J'ai même mis l'optocoupleur de la carte 4 leds sur la carte 3 leds et la carte 3 leds fonctionne.
Donc optocoupleur OK
2- Pb de la carte CI que j'ai fait : J'ai donc mis l'Arduino avec le PRG 3 leds et la carte fonctionne parfaitement. Donc le CI est OK.
J'ai mis l'Arduino avec le prg 4 leds sur la carte 3 leds et le fonctionnement n'est pas bon : les cdes DCC ne produisent rien.
L'allumage des leds est celui décrit précédemment.
Pour mettre le programme dans l'Arduino j'ai fait un copier du PRG en faisant sélectionner puis copier et mis ensuite dans l'éditeur de programmation Arduino. Est-ce cela qui pose un PB. Est-il possible d'avoir le fichier .ino et téléchargement ?
Merci pour votre aide car là je bloque complètement.
Dans l'attente de votre réponse.
Arduinotement vôtre.
Pierre
-
Bonsoir,
vous pouvez essayer cette version qui ne doit pas être très différente de celle de trimarco232
https://forum.locoduino.org/index.php?topic=1429.msg15510#msg15510
je pense avoir corrigé le bug.
-
Cher MSPORT,
Je viens de télécharger ton PRG. Mais comme je n'ai pas fait TRES attention au premier essai PAF le chien.
Ensuite j'ai regardé ton PRG et j'ai vu que l'adresse de début était 10 ... Petit piège car j'ai fait mon premier test à partir de l'adresse 90 ! C'est ce qui était pour le 3 leds et que TRIMARCO232 avait pris aussi.
Et là essai à partir de l'adresse 10 tout fonctionne : BRAVO et surtout UN GRAND MERCI pour ton aide.
Dois-je déduire que le PRG de TRIMARCO que j'ai fait en copier coller pose un PB par cette méthode de copier coller (et non pas du PRG lui-même).
Encore tous mes remerciements à vous deux. Cela me (nous) montre que la communauté ARDUINO est TOP.
Je ferais des photos des cartes et je les mettrais sur le forum.
ARDUINOTEMENT VOTRE
Pierre
-
Très heureux que ça marche.
C'est probablement dans le transport que quelques octets se sont perdus puisque c'est également avec un copié collé que j'ai récupéré le programme de trimarco232 et qu'il a fonctionné sans problème (avec une adresse de départ modifiée)
-
bonjour,
félicitations à Pierre, l'audace (car il en faut à ce stade) a payé 8)
j'avais édité mon pgm, principalement pour clarifier les commentaires, mais peut-être un loup s'y est glissé
quoiqu'il en soit, adopter le pgm de msport me semble la bonne option, car msport a déjà (si j'ai bien suivi) fait quelque chose pour adapter ça aux logiciels qui décalent les adresses : on aura bien un jour une demande en ce sens, msport sera prêt ;)
je laisse mon pgm pour mémoire, ça sera peut-être utile quand on envisagera les allumages et extinctions progressifs