Auteur Sujet: "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"  (Lu 698 fois)

trimarco232

  • Full Member
  • ***
  • Messages: 175
    • Voir le profil
suite à la demande de Pierrre sur 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
« Modifié: juin 24, 2022, 03:25:47 pm par trimarco232 »

msport

  • Hero Member
  • *****
  • Messages: 1792
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #1 le: juin 24, 2022, 11:01:19 am »
Bonjour,

parfait, testé sur les premières adresses sans problème.
Cordialement

trimarco232

  • Full Member
  • ***
  • Messages: 175
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #2 le: juin 24, 2022, 11:36:48 am »
Bonjour msport,
merci pour le test, car j'ai dû me contenter de faire des simulations

PETER41

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #3 le: juin 24, 2022, 05:11:46 pm »
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

PETER41

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #4 le: juillet 05, 2022, 06:39:25 pm »
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

PETER41

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #5 le: juillet 07, 2022, 04:55:17 pm »
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

msport

  • Hero Member
  • *****
  • Messages: 1792
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #6 le: juillet 07, 2022, 10:10:50 pm »
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.
Cordialement

PETER41

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #7 le: juillet 08, 2022, 06:46:30 pm »
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

msport

  • Hero Member
  • *****
  • Messages: 1792
  • HO avec DCC++ en DIY Réseaux très éphémères
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #8 le: juillet 08, 2022, 08:00:29 pm »
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)
Cordialement

trimarco232

  • Full Member
  • ***
  • Messages: 175
    • Voir le profil
Re : "extension 4 feux pour le décodeur de signaux à 2 ou 3 feux"
« Réponse #9 le: juillet 12, 2022, 12:38:10 pm »
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