Auteur Sujet: Levée de boucliers!  (Lu 550 fois)

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 495
    • Voir le profil
Re : Re : Levée de boucliers!
« Réponse #15 le: août 12, 2019, 02:34:39 pm »
Allumer éteindre des leds parait simple comme "blink" mais ca devient plus "touchy" des lors que tu combines avec des adresses DCC, des combinaisons d'affichage, des états particuliers, des groupes de leds sur des plages d adresses... Et la tu as deja perdu beacoup de monde!

Et justement, Commanders comme Accessories ne sont pas perdus, ils sont faits pour ça ! Pour Commanders, une ligne unique déclare la présence d'un décodeur DCC. Et pour Accessories, chaque Led ou moteur réagit à des événements qui intègrent déjà l'adresse DCC... Je ne force personne, je dis juste que faire mieux qu'allumer une Led, on le fait déjà très bien, et que ce serait dommage de ne pas capitaliser sur ce qui existe et qui marche (et réponds parfaitement au 'cahier' des charges) !

laurentr

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re : Levée de boucliers!
« Réponse #16 le: août 13, 2019, 04:59:30 pm »
Bonjour Thierry

Effectivement la bibliothèque ACCESSOIRES va pouvoir servir :).

J ai directement pris l'exemple SignalFrench dont je vais modifier le prisme avec les éléments d'approche ci dessous.
Cela me semble jouable... Sauf si tu vois directement des restrictions...???

Cette approche va permettre une plus grande modularité ( tous les tpe de cibles, et des combinaisons de cible SIGNAL FEUX et ID ou autres écrans lumineux
Tenir compte de combinaisons inédites au delà des 16 déja en place (0 à 15 déjà présentes)

Ce que je n ai pas encore identifie c est comment créer "deux groupes" de sorties répondant chacun a une série d adresses DCC... Mais ca va venir!

De même avec cet exemple comment on connait les différentes adresses accessoires utilisées en fonction du nombre de combinaisons que l on pousse...

Je dois encore m y plonger plus avant! Néanmoins si quelqu'un sait m expliquer le mécanisme ( et les lignes du codes associées) j avancerai plus vite!

Voici déjà un début de code review avec les hypothèses de posées.
J attaquerai ensuite la distribution des valeurs dans la classe.

//-------------------------------------------------------------------
// Le feu Francais le plus complexe presente un panneau (ou cible) dit unifie de type dit "H".
// Il est compose d'au maximum 10 lampes (dont l'oeilleton).
// Plusieurs lampes de meme ordre sont allumees systematiquement en meme temps ce qui reduit le nombre des sorties a utiliser a 8 ( RAL et RRAL).
// Tous les autres panneaux SNCF (hormis la cible circulaire) sont des combinaisons simplifiées de ce dispositif.
// Les combinaisons proposees sont toutes de type "mode nominal" et pas de mode dégrade ou en anomalie.( Ex carre brule avec 1 seul rouge et pas d'oeilleton) mais on pourrait ajouter ce cas precis facilement si besoin
// (avec le cablage propose il ne sera pas possible de n allumer qu un des deux jaunes du RAL ou RRAL)
// Les rouges du Carre et du semaphore sont gérés de manière autonome
// le cablage de l'oeilleton est facultatif
////////////////////////////////////////////////
// Panneau unifie type H:
//
//        |7|
//   |6| |6|
//   |5| |7|
//   |4|
//   |3|
//   |2|
//   |1|
//    |0|
//
// Avec
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre ou Carre Violet
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal branche montage en parallele
// 7 = double jaune vertical branche montage en parallele
//
/////////////////////////////////////////////////////////////////
// Panneau unifie type I (dite cible 2 feux)(sans oeilleton):
//
//             |5|
// |5||4|   ou |4|
//
// 4= violet (carreviolet)
// 5= blanc (manoeuvre)
//
// I1 = Man,CV
/////////////////////////////////////////////////////////////////
// Panneau unifie type A (dite cible 3 feux)(sans oeilleton)
// A1
//  |3|
//  |2|
//  |1|
//
// A2
//  |3|
//  |2|
//  | |
//
//
// 1 = jaune (Avertissement)
// 2 = rouge (semaphore)
// 3 = vert (Voie Libre)
//
// A1 = Av,VL,S
// A2 = Vl,S
/////////////////////////////////////////////////////////////////
// Panneau unifie type B
// B1
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
//
// B1 = Oe,Av,VL,S,C
////////////////////////////////////////////////////////////////
// Panneau de type E
// E1
//   |6| |6|
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
//
// E2
//   |6| |6|
//   | |
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
// 6 = double jaune horizontal (montage en parallele)
//
// E1 = Oe,Av,VL,S,C,RAL
// E2 = Oe,Av,Vl,S,RAL
//
/////////////////////////////////////////////////////////////////////
// Panneau de type F
// F1
//   |6| |6|
//   |5|
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal (montage en parallele)
//
// F1 = Oe,Av,VL,S,C,M,RAL
// ///////////////////////////////////////////////////////////////////
// Cible de type G
// G1
//       |7|
//   |6| |6|
//   |4| |7|
//   |3|
//   |2|
//   |1|
// |0|
//
// G2
//       |7|
//   |5| | |
//   |4| |7|
//   |3|
//   |2|
//   |1|
// |0|
//
// G3
//       |7|
//   | | | |
//   |4| |7|
//   |3|
//   |2|
//   |1|
// |0|
//
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal (montage en parallele)
// 7 = double jaune vertical (montage en parallele)
//
// G1 = Oe,Av,VL,S,C,RAL,RRAL
// G2 = Oe,Av,Vl,S,C,M,RRAL
// G3 = Oe,Av,Vl,S,C,RRAL
/////////////////////////////////////////////////////////////////
// cible de type H
//
// H1
//       |7|
//   |6| |6|
//   |5| |7|
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre ou Carre Violet
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal (montage en parallele)
// 7 = double jaune vertical (montage en parallele)
//
// H1= Oe,Av,VL,S,C,Man,Ral,RRAL
// H2= Oe,Av,VL,S,Cv,Man,Ral,RRAL
//
//////////////////////////////////////////////////////////////////
// Cible de type D (Disque) ou R (Ronde)
//
// forme circulaire
// C1
//   | |      | |
//      |3|
//   |2*|      |2**|
//      |1|
//
// 1 = jaune (Avertissement)
// 2* = jaune (disque) (en combinaison avec 2**)
// 2** = rouge (disque) (en combinaison avec 2*)
// 3 = vert ( Voie Libre)
//
//
// C2
//   | |      | |
//      |3|
//   |2*|      |2**|
//      | |
//
//
// 2* = jaune (disque) (en combinaison avec 2**)
// 2** = rouge (disque) (en combinaison avec 2*)
// 3 = vert ( Voie Libre)
//
// C3
//   | |      | |
//      |3|
//   | |      | |
//      |1|
//
//
// 1 = jaune (Avertissement)
// 3 = vert ( Voie Libre)
//
//
// C4
//   |6|      |6|
//      |3|
//   | |      | |
//      |1|
//
//
// 1 = jaune (Avertissement)
// 3 = vert ( Voie Libre)
// 6 = double jaune horizontal branche montage en parallele
//
//
//
// C1 = Av,VL,D,RAL
// C2 = TO DO
// C3 = TO DO
// C4 = TO DO
/////////////////////////////////////////////////////////////////////////////////////////////

laurentr

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re : Levée de boucliers!
« Réponse #17 le: août 14, 2019, 03:44:15 pm »
Bonjour

Il faut installer les biblotheques suivantes:
ACCESSORIES
COMMANDERS
DIO2

J ai progresse dans l écriture mais j ai eu  quelques mauvaises surprises à la compilation!
SPARKFUN1509.h manquant ==> solution installation de la bibliothèque gérant le 1509.
Idem pour le SH74HC595==> installation de la bibliothèque correspondante

Une fois ces désagréments passés la série continue mais sur un autre registre cette fois liée au code proprement dit:

DCCID et DCC ACTIVATION posent problème



...\Documents\Arduino\sketch_aug12a\sketch_aug12a.ino: In member function 'virtual void SignalArduinoPattern::Move(long unsigned int)':

sketch_aug12a:77:25: error: 'DCCID' was not declared in this scope

   int etat = (DCCID(inId) - this->startingDcc) * 2 + DCCACTIVATION(inId);

                         ^

sketch_aug12a:77:72: error: 'DCCACTIVATION' was not declared in this scope

   int etat = (DCCID(inId) - this->startingDcc) * 2 + DCCACTIVATION(inId);

Si certains savent comment resoudre cet élément bloquant on pourra ensuite regarder le reste que je glisse ci dessous...

D avance merci

Laurent.
                                                                        ^

/*************************************************************
project: <Accessories>
author: <Thierry PARIS>
co author: <Laurent ROEKENS>
description: <8 leds for a french railroad signal>
*************************************************************/

#include "Commanders.h"
#include "Accessories.h"

#define NB_LEDS_MAX      16 //LTR modif 20>16 (qui vont etre repartis en 2 groupes de 8 leds
#define PATTERN_NB_LEDS_MAX 4 // sauf cas des ID max = 6ID + 2 Accesoires
#define PATTERN_END_LIST  127
#define DCCSTART      10
// ajout pour compatibilite DR5000 #define kDCC_INTERRUPT 80
#define kDCC_INTERRUPT 80

//-------------------------------------------------------------------
// This class defines a light signal by giving patterns of lights:
// like the state -x--BB-- for a signal with 8 lights (modif LTR).
// - = 0 = OFF
// x = 1 = ON
// B = BLINK
// Where x means light on, - means off, and B is blink.
//-------------------------------------------------------------------

class SignalArduinoPattern : public AccessoryLightMulti
{
private:
  const uint8_t *pPatterns;
  const uint8_t *pRealStates;
  int startingDcc;
  int blinkDuration;

public:
  inline SignalArduinoPattern() {}
  void beginSignal(uint8_t inNbLeds, const int *inpPins, int inStartingDcc, int inBlinkDuration, const uint8_t *inPatterns, const uint8_t *inpRealStates = 0);
  void Move(unsigned long inId);

  static int GetStatesNumber(const uint8_t *pStates);
};

void SignalArduinoPattern::beginSignal(uint8_t inNbLeds, const int *inpPins, int inStartingDcc, int inBlinkDuration, const uint8_t *inPatterns, const uint8_t *inpRealStates)
{
  begin(0, inNbLeds, 0);
  for (int led = 0; led < inNbLeds; led++)
  {
    PortOnePin *pPort = new PortOnePin();
    pPort->begin(inpPins[led], DIGITAL);
    this->beginLight(led, pPort, 255);
  }

  this->startingDcc = inStartingDcc;
  this->blinkDuration = inBlinkDuration;
  this->pPatterns = inPatterns;
  this->pRealStates = inpRealStates;

/*#ifdef DEBUG_MODE
  // Pass through all states during 5s to check
  for (int i = 0; i < SignalArduinoPattern::GetStatesNumber(this->pRealStates); i++)
  {
    this->Move(this->startingDcc + (i / 2), i % 2);
    unsigned long start = millis();
    while (millis() - start < 1000)
      Accessories::loop();
    this->LightOff();
    start = millis();
    while (millis() - start < 1000)
      Accessories::loop();
  }
#endif*/
}

void SignalArduinoPattern::Move(unsigned long inId)
{
  int pospattern = 0;
  int etat = (DCCID(inId) - this->startingDcc) * 2 + DCCACTIVATION(inId);

  // All leds off
  for (unsigned char led = 0; led < this->GetSize(); led++)
    this->LightOff(led);

  char symbText[16];
  for (int i = 0; i < 16-1; i++)
    symbText = '.';

  symbText[15] = 0;

  // Change affected leds in the list
  for (int led = 0; led < PATTERN_NB_LEDS_MAX; led++)
  {
    uint8_t c = pgm_read_byte(this->pPatterns + (etat * PATTERN_NB_LEDS_MAX) + pospattern++);

    if (c > 0 && c <= 100)
    {
      this->SetBlinking(c-1, 0);
      this->LightOn(c-1);
      symbText[c-1] = 'O';
    }
    else
      if (c > 100)
      {
        this->SetBlinking(c-101, this->blinkDuration);
        this->Blink(c-101);
        symbText[c-101] = 'B';
      }
  }

  Serial.println(symbText);
}

int SignalArduinoPattern::GetStatesNumber(const uint8_t *pStates)
{
  for (int i = 0;; i++)
  {
    uint8_t c = pgm_read_byte(pStates + i);
    if (c == PATTERN_END_LIST)
      return i;
  }

  return 9999;
}

//-------------------------------------------------------------------
// Le feu Francais le plus complexe presente un panneau (ou cible) dit unifie de type "H".
// Il est compose d'au maximum 10 lampes (dont l'oeilleton).
// Plusieurs lampes de meme ordre sont allumees systematiquement en meme temps ce qui reduit le nombre des sorties a utiliser a 8 ( RAL et RRAL).
// Tous les autres panneaux SNCF (hormis la cible circulaire) sont des combinaisons simplifiées de ce dispositif.
// Les combinaisons proposees sont toutes de type "mode nominal" et pas de mode dégrade ou en anomalie.( Ex carre brule avec 1 seul rouge et pas d'oeilleton) mais on pourrait ajouter ce cas precis facilement si besoin
// (avec le cablage propose il ne sera pas possible de n allumer qu un des deux jaunes du RAL ou RRAL)
// Les rouges du Carre et du semaphore sont gérés de manière autonome
// le cablage de l'oeilleton est facultatif
////////////////////////////////////////////////
// Panneau unifie type H:
//
//       |7|
//   |6| |6|
//   |5| |7|
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
// Avec
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre ou Carre Violet
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal branche montage en parallele
// 7 = double jaune vertical branche montage en parallele
//
/////////////////////////////////////////////////////////////////
// Panneau unifie type I (dite cible 2 feux)(sans oeilleton):
//
//             |5|
// |5||4|   ou |4|
//
// 4= violet (carreviolet)
// 5= blanc (manoeuvre)
//
// I1 = Man,CV
/////////////////////////////////////////////////////////////////
// Panneau unifie type A (dite cible 3 feux)(sans oeilleton)
// A1
//  |3|
//  |2|
//  |1|
//
// A2
//  |3|
//  |2|
//  | |
//
//
// 1 = jaune (Avertissement)
// 2 = rouge (semaphore)
// 3 = vert (Voie Libre)
//
// A1 = Av,VL,S
// A2 = VL,S
/////////////////////////////////////////////////////////////////
// Panneau unifie type B
// B1
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
//
// B1 = Oe,Av,VL,S,C
////////////////////////////////////////////////////////////////
// Panneau de type E
// E1
//   |6| |6|
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
//
// E2
//   |6| |6|
//   | |
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
// 6 = double jaune horizontal (montage en parallele)
//
// E1 = Oe,Av,VL,S,C,RAL
// E2 = Oe,Av,VL,S,RAL
//
/////////////////////////////////////////////////////////////////////
// Panneau de type F
// F1
//   |6| |6|
//   |5|
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal (montage en parallele)
//
// F1 = Oe,Av,VL,S,C,M,RAL
// ///////////////////////////////////////////////////////////////////
// Cible de type G
// G1
//       |7|
//   |6| |6|
//   |4| |7|
//   |3|
//   |2|
//   |1|
// |0|
//
// G2
//       |7|
//   |5| | |
//   |4| |7|
//   |3|
//   |2|
//   |1|
// |0|
//
// G3
//       |7|
//   | | | |
//   |4| |7|
//   |3|
//   |2|
//   |1|
// |0|
//
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal (montage en parallele)
// 7 = double jaune vertical (montage en parallele)
//
// G1 = Oe,Av,VL,S,C,RAL,RRAL
// G2 = Oe,Av,Vl,S,C,M,RRAL
// G3 = Oe,Av,Vl,S,C,RRAL
/////////////////////////////////////////////////////////////////
// cible de type H
//
// H1
//       |7|
//   |6| |6|
//   |5| |7|
//   |4|
//   |3|
//   |2|
//   |1|
// |0|
//
// 0 = oeilleton blanc
// 1 = jaune (Avertissement)
// 2 = rouge ( sémaphore)
// 3 = vert ( Voie Libre)
// 4 = feu rouge superieur du Carre ou Carre Violet
// 5 = blanc (manoeuvre)
// 6 = double jaune horizontal (montage en parallele)
// 7 = double jaune vertical (montage en parallele)
//
// H1= Oe,Av,VL,S,C,Man,Ral,RRAL
// H2= Oe,Av,VL,S,Cv,Man,Ral,RRAL
//
//////////////////////////////////////////////////////////////////
// Cible de type D (Disque) ou R (Ronde)
//
// forme circulaire
// C1
//   | |      | |
//      |3|
//   |2*|      |2**|
//      |1|
//
// 1 = jaune (Avertissement)
// 2* = jaune (disque) (en combinaison avec 2**)
// 2** = rouge (disque) (en combinaison avec 2*)
// 3 = vert ( Voie Libre)
//
//
// C2
//   | |      | |
//      |3|
//   |2*|      |2**|
//      | |
//
//
// 2* = jaune (disque) (en combinaison avec 2**)
// 2** = rouge (disque) (en combinaison avec 2*)
// 3 = vert ( Voie Libre)
//
// C3
//   | |      | |
//      |3|
//   | |      | |
//      |1|
//
//
// 1 = jaune (Avertissement)
// 3 = vert ( Voie Libre)
//
//
// C4
//   |6|      |6|
//      |3|
//   | |      | |
//      |1|
//
//
// 1 = jaune (Avertissement)
// 3 = vert ( Voie Libre)
// 6 = double jaune horizontal branche montage en parallele
//
//
//
// C1 = Av,VL,Disque,RAL
// C2 = VL,Disque
// C3 = Av,VL
// C4 = Av,VL,RAL
/////////////////////////////////////////////////////////////////////////////////////////////

// La norme SCNF veut qu'il y ait quatre leds allumées au maximum, oeilleton compris.
// La liste décrit, 4 par 4, les numéros des leds allumées : positif allumé,
// supérieur à 100 clignotant, 0 inutilisé. Ce qui signifie que les numéros commencent à 1.
// Le code texte sur chaque ligne "--x-----" symbolise plus clairement les états.
// Enfin les numéros de chaque ligne sont notés de 0 à 24. Ils vont être réutilisés plus tard.
// ex 101 signifie 1ere sortie clignotante
// ex 102 signifie 2eme sortie clignotante
// etc
/////////////////////////////////////////////////////////////////////////////////////////////
// ordre de distribution
// Oe sortie 1
// Av sortie 2
// S sortie 3
// VL sortie 4
// C ou CV sortie 5
// Man sortie 6
// RAL sortie 7
// RRAL sortie 8
/////////////////////////////////////////////////////////////////////////////////////////////

const uint8_t SignalFrStates[] PROGMEM = {
            //  12345678
  101,102,103,104,              // "BBBB----"       0:(Oe,Av,VL,S)Cli
  105,106,107,108,              // "----BBBB"       1:(C/Cv,Man,RAL,RRAL)Cli 
  0,0,0,0,                      // "--------"       2: ALL OFF
  0, 3, 5, 0,                   // "--x-x---"       3: CARRE
  0, 5, 0, 0,                   // "----x---"       4: CARRE VIOLET
  1, 3, 0, 0,                   // "x-x-----"       5: Semaphore
  1, 103, 0, 0,                 // "x-x-----"       6: Rouge Cli 
  0, 3, 0, 0,                   // "-----x--"       7: Man
  0, 103, 0, 0,                 // "-----x--"       8: Man limitée
  1, 8, 0, 0,                   // "x------x"       9: RRAL 30
  1, 108, 0, 0,                 // "x------B"       10:RRAL 60
  1, 2, 0, 0,                   // "xx------"       11: Avertissement
  1, 7, 0, 0,                   // "x-----x-"       12: RAL 30
  1, 102, 0, 0,                 // "xB------"       13: Jaune Cli
  1, 107, 0, 0,                 // "x-----B-"       14: RAL 60
  1, 104, 0, 0,                 // "x--B----"       15: RAL 160
  1, 4, 0, 0,                   // "x--x----"       16: VL
  1, 0, 0, 0,                   // "xx-----x"       17: RRAL 30 + Av         
  1, 0, 0, 0,                   // "xB-----x"       18: RRAL 30 + Jaune Cli         
  1, 0, 0, 0,                   // "xx-----B"       19: RRAL 60 + Av         
  1, 0, 0, 0,                   // "xB-----B"       20: RRAL 60 + Jaune Cli         
  1, 0, 0, 0,                   // "xB----B-"       21: RAL 60 +Jaune Cli         
  0, 3, 0, 0,                   // "--x-----"       22: Disque
  0, 0, 0, 0,                   // "--------"       23: RESERVE         
  0, 0, 0, 0,                   // "--------"       24: RESERVE         
                   
            //  12345678
  PATTERN_END_LIST  // end of the list !
};

// Pour chaque type de feu, il n'y a que certains états de la liste ci-dessus qui sont utilisables.

// const uint8_t SignalFr3[] PROGMEM = { 0, 1, 2, 3, 4, PATTERN_END_LIST };
// const uint8_t SignalFr5[] PROGMEM = { 0, 1, 2, 3, 4, 5, 6, PATTERN_END_LIST };
// const uint8_t SignalFr7[] PROGMEM = { 0, 1, 2, 3, 4, 5, 6, 7, 11, 12, PATTERN_END_LIST };
// const uint8_t SignalFr9[] PROGMEM = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, PATTERN_END_LIST };

const uint8_t SignalI1[] PROGMEM = { 0, 1, 2, 4, 7, 8, PATTERN_END_LIST }; // I1 = Man,CV
const uint8_t SignalA1[] PROGMEM = { 0, 1, 2, 5, 6, 11, 13, 15, 16, PATTERN_END_LIST }; // A1 = Av,VL,S
const uint8_t SignalA2[] PROGMEM = { 0, 1, 2, 5, 6, 15, 16, PATTERN_END_LIST }; // A2 = VL,S
const uint8_t SignalB1[] PROGMEM = { 0, 1, 2, 3, 5, 6, 11, 13, 15, 16, PATTERN_END_LIST }; // B1 = Oe,Av,VL,S,C
const uint8_t SignalE1[] PROGMEM = { 0, 1, 2, 3, 4, 6, 11, 13, 15, 16, 12, 14, 21, PATTERN_END_LIST }; // E1 = Oe,Av,VL,S,C,RAL
const uint8_t SignalE2[] PROGMEM = { 0, 1, 2, 5, 6, 11, 13, 15, 16, 12, 14, 21, PATTERN_END_LIST }; // E2 = Oe,Av,VL,S,RAL
const uint8_t SignalF1[] PROGMEM = { 0, 1, 2, 3, 5, 6, 7, 8, 11, 13, 14, 15, 16, 12, 14, 21, PATTERN_END_LIST }; // F1 = Oe,Av,VL,S,C,M,RAL
const uint8_t SignalG1[] PROGMEM = { 0, 1, 2, 3, 5, 6, 9, 10, 11, 12, 13, 15, 16, 12, 13, 14, 15, 16, 17,18,19,20,21, PATTERN_END_LIST }; // G1 = Oe,Av,VL,S,C,RAL,RRAL
const uint8_t SignalG2[] PROGMEM = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, PATTERN_END_LIST }; // G2 = Oe,Av,Vl,S,C,M,RRAL
const uint8_t SignalG3[] PROGMEM = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 15, 16, 17, 18, 19, 20,  PATTERN_END_LIST }; // G3 = Oe,Av,VL,S,C,RRAL
const uint8_t SignalH1[] PROGMEM = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, PATTERN_END_LIST }; // H1= Oe,Av,VL,S,C,Man,RAL,RRAL
const uint8_t SignalH2[] PROGMEM = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, PATTERN_END_LIST }; // H2= Oe,Av,VL,S,Cv,Man,RAL,RRAL
const uint8_t SignalC1[] PROGMEM = { 0, 1, 2, 11, 12, 13, 14 , 15, 16, 22, PATTERN_END_LIST }; // C1 = Av,VL,Disque,RAL
const uint8_t SignalC2[] PROGMEM = { 0, 1, 2, 15, 16, 22, PATTERN_END_LIST }; // C2 = VL,Disque
const uint8_t SignalC3[] PROGMEM = { 0, 1, 2, 11, 13, 15, 16, PATTERN_END_LIST }; // C3 = Av,VL
const uint8_t SignalC4[] PROGMEM = { 0, 1, 2, 11, 12, 13, 14, 15, 16, 21, PATTERN_END_LIST }; // C4 = Av,VL,RAL


// 0:(Oe,Av,VL,S)Cli
// 1:(C/Cv,Man,RAL,RRAL)Cli 
// 2: ALL OFF
// 3: CARRE
// 4: CARRE VIOLET
// 5: Semaphore
// 6: Rouge Cli 
// 7: Man
// 8: Man limitée
// 9: RRAL 30
// 10: RRAL 60
// 11: Avertissement
// 12: RAL 30
// 13: Jaune Cli
// 14: RAL 60
// 15: RAL 160
// 16: VL
// 17: RRAL 30 + Av         
// 18: RRAL 30 + Jaune Cli         
// 19: RRAL 60 + Av         
// 20: RRAL 60 + Jaune Cli         
// 21: RAL 60 +Jaune Cli         
// 22: Disque
// 23: RESERVE         
// 24: RESERVE 


// Liste des états pour un feu rond.

// const uint8_t SignalFrStatesRound[] PROGMEM = {
  //  123456789012
 // 3, 0, 0, 0, // "--x---------" 0: voie libre
 // 103, 0, 0, 0, // "--B---------" 1: voie libre limitée à 160km/h
 // 101, 0, 0, 0, // "B-----------" 2: Avertissement arrêt très proche.
 // 1, 0, 0, 0, // "x-----------" 3: Avertissement arrêt.
 // 10, 11, 0, 0, // "---------xx-" 4: Conduite à vue (signal rond seulement)
 // 6, 7, 0, 0, // "-----xx-----" 5: Vitesse réduite à 30
 // 106, 107, 0, 0, // "-----BB-----" 6: Vitesse réduite à 60
 // 101, 106, 107, 0, // "B----BB-----" 7: Vitesse réduite à 60 + avertissement
            //  123456789012
  // PATTERN_END_LIST  // end of the list !
// };

// Tous les états sont utilisables, à priori.

// const uint8_t SignalFrRound[] PROGMEM = { 0, 1, 2, 3, 4, 5, 6, 7, PATTERN_END_LIST };

// Four leds on only. First led is 1. Negative led number will blink.

// Liste des états pour un feu horizontal.

// const uint8_t SignalFrStatesHorizontal[] PROGMEM = {
  //  123456789012
//  1, 0, 0, 0,   // "x-----------"   0: Vitesse de manoeuvre (feu horizontal)
//  101, 0, 0, 0, // "B-----------"   1: Vitesse de manoeuvre réduite (feu horizontal)
//  2, 0, 0, 0,   // "-x----------"   2: idem AbsoluteStop mais sur un signal horizontal ou deux feux.
          //  123456789012
//  PATTERN_END_LIST  // End of the list
// };

// Tous les états sont utilisables, à priori.

// const uint8_t SignalFrHorizontal[] PROGMEM = { 0, 1, 2, PATTERN_END_LIST };

SignalArduinoPattern signal;

// Commanders

#ifdef VISUALSTUDIO
ButtonsCommanderKeyboard  push;
#else
ButtonsCommanderPush push;
#endif

// Accessories

// Drivers

// #define signalPattern SignalFr9
// #define NB_LEDS     12

#define signalPattern SignalH1
#define NB_LEDS     8

// int pins[NB_LEDS] = { 3, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 };
int pins[NB_LEDS] = { 3, 4, 5, 6, 7, 8, 9, 10 };

void ReceiveEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEventType, int inEventData)
{
  int id = DCCID(inId);
  if (id >= DCCSTART && id < DCCSTART + (SignalArduinoPattern::GetStatesNumber(signalPattern) + 1) / 2)
    signal.Move(inId);

  Accessories::ReceiveEvent(inId, (ACCESSORIES_EVENT_TYPE)inEventType, inEventData);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Setup
//
void setup()
{
  Serial.begin(115200);
  //while (!Serial);    // For Leonardo only. No effect on other Arduino.

  Commanders::begin(ReceiveEvent, LED_BUILTIN);
  Accessories::begin();

  // Commanders setup

  DccCommander.begin(0x00, 0x00, digitalPinToInterrupt(3));

  // UNDEFINED_ID here means that this id is not significant.
#ifdef VISUALSTUDIO
  push.begin(UNDEFINED_ID, '0');
#else
  push.begin(UNDEFINED_ID, 17);
#endif

  int nb_etats = SignalArduinoPattern::GetStatesNumber(signalPattern);

  // Ce petit bouton va permettre de passer en revue tous les codes dcc des feux en séquence...
 
  int dcc = DCCSTART;
  bool etat = false;
  for (int i = 0; i < nb_etats; i++)
  {
    if (!etat)
    {
      push.AddEvent(DCCINT(dcc, 0));
      etat = true;
    }
    else
    {
      push.AddEvent(DCCINT(dcc, 1));
      dcc++;
      etat = false;
    }
  }

  signal.beginSignal(NB_LEDS, pins, DCCSTART, 500, SignalFrStates, signalPattern);
}

void loop()
{
  Accessories::loop();

  Commanders::loop();
}

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 495
    • Voir le profil
Re : Levée de boucliers!
« Réponse #18 le: août 14, 2019, 05:25:38 pm »
Accessories comme Commanders se configurent à partir de leur fichier .h respectif.

Dans Accessories.h, enlever le commentaire de la ligne

//#define NO_EXPANDER
et comme ça, l'installation des sous-bib pour le 1509 et le 74HC ne sont plus nécessaires.

A l'inverse, le DCC n'est pas activé par défaut dans Commanders, vu que l'essentiel des usages de la bibliothèque se concentre sur les boutons en tout genre. Il faut donc mettre en commentaire l'une des deux lignes

#define NO_DCCCOMMANDER
#define NO_DCCCOMMANDERNMRA

et ainsi obtenir tout ce qui va avec le DCC, dont les macros dont tu parles. Je conseillerai d'utiliser la bibliothèque NMRA plutôt que celle de base. Elle est plus fiable.

Dans les deux bibliothèques, profites-en pour retirer de la compilation par le même moyen tout ce qui ne te servira pas, comme le shield l293d ou les moteurs pas à pas (stepper) dans Accessories. Pour chacune, tu peux double cliquer sur le fichier extras/Doc/index.html pour avoir une doc détaillée en Anglais des classes, defines et autres fonctionnements obscurs. N'hésites pas à me signaler des manques dans cette doc si besoin.

laurentr

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re : Levée de boucliers!
« Réponse #19 le: août 14, 2019, 06:43:58 pm »
Merci Thierry

Non sans mal mais c est en place!
J ai du garder la bibliothèque DCCCOMMANDER standard car la DCCCOMMANDERNMRA ne semblait pas fonctionner avec le code.

La compile pousse au bout.

Il (me) reste a comprendre: ( pour mettre en oeuvre)

1/ comment fixer une adresse DCC de base pour le premier état (j imagine que l incrément en fonction du nombre de combinaisons augmentera de fait en mêème temps) ( Est ce que cela serait la ligne DCC Start XX ou X est la valeur de base du 1er etat du decodeur?)
2/ faire le choix du type de signal a commander ( I1, A1,A2,B1, E1,...H1,H2, C1,...C4)

Merci pour votre aide
Laurent



laurentr

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re : Levée de boucliers!
« Réponse #20 le: août 15, 2019, 12:48:49 am »
Bonsoir

J ai modifie la ligne suivante

DccCommander.begin(0x00, 0x00, digitalPinToInterrupt(2)); pour que la PIN D2 qui reçoit le signal DCC via l optocoupleur soit la PIN d entree du signal

Mais... ensuite ou est la valeur a saisir pour l adresse initiale? ( car rien ne bouge derrière...)

Big questions...

Je ne dois pas etre bien loin du "vrai"... pls help!
Laurent

laurentr

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re : Levée de boucliers!
« Réponse #21 le: août 16, 2019, 10:16:51 pm »
Bonsoir

L un de vous aurait il les syntaxes  pour

Fixer l adresse dcc de base ( est ce dccsstart?)
Confirmer que D2 peut bien recevoir le signal dcc?
Confirmer que les pins d3 a d10 sont bien des sorties.
Enfin ce qu il peut manquer pour faire fonctionner le tout...

Pour mémoire d3 d4 d5 d6 d7 d8 d9 et d10 doivent être des sorties et correspondre aux états de sorties œilleton av vl s c/cv man ral rral.

D avance merci
Laurent

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 495
    • Voir le profil
Re : Levée de boucliers!
« Réponse #22 le: août 16, 2019, 10:50:26 pm »
Bonjour

Ca va fonctionner sur un Mega dont la broche 2 est capable de faire ce boulot, mais pas sur un Uno ou Nano. Je n'ai pas retrouvé dans le sujet de référence à un modèle d'Arduino, donc attention... Les autres broches sont ou des entrées ou des sorties, au choix.

La classe SignalArduinoPattern  repose sur la classe AccessoryLightMulti. Celle ci est une liste de Leds dont le comportement est régit par deux entiers, un pour l'allumage et l'autre pour le clignotement. Ces entiers sont codés sur 16 bits, ce qui signifie qu'un signal ne pourra pas avoir plus de 16 leds. Chaque entier est utilisé comme un champs de bits, chacun représentant une led. Chaque Led est associée à un port qui va permettre de l'alimenter.

L'accessoire contient également une liste d'identifiants qui représentent toutes les combinaisons d'allumage/clignotement possibles. Chaque combinaison est nommée par un identifiant qui, dans le cas du DCC, est un mix entre une adresse DCC de décodeur d'accessoires et un numéro d'accessoire. C'est de rôle de la macro de DCCINT() d'assembler ces deux petits entiers pour en faire un gros qui devient l'identifiant d'une combinaison donnée.

Je suis en train de refaire SignalFrench pour permettre de fixer le code DCC de chaque etat individuellement.

laurentr

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re : Levée de boucliers!
« Réponse #23 le: août 16, 2019, 11:41:26 pm »
Bonsoir Thierry

Merci pour tes éléments de réponse.
Effectivement étant sur un NANO et utilisant la broche D2 comme entrée ... cela ne peut fonctionner ainsi... comme je l’esperais!

Idéalement il’faudrait Pouvoir dans le code:
Choisir le modèle d arduino (nano,uno ou mega)
Un modèle doit pouvoir gerer 2 signaux de 8 feux.( et jusqu à n combinaisons)( n Max = 3^8 = 6561) (3 = off, on ou blink)  Dans mon exemple plus haut je suis parti sur 24 combinaisons de base ce qui occupe 6 adresses dcc accessoire de base à 4 états ou 12 à 2 états. Donc saisir le nombre de signaux gérés ( ici 1 ou 2)
La dernière entrée saisie affiche sur le signal la combinaison Attendue et efface les autres du même signal)
Avoir l entrée du signal DCC sur D2 ( ce qui est assez commun.)
Saisir le nombre de combinaisons pour le signal 1 idem pour le signal  2
Pouvoir fixer l ID de base du signal 1 ( les ID SUIVANTES S AJOUTERONT simplement tant que des combinaisons sont à compléter, idem pour le signal 2 ( les plages d adresses peuvent être commun ou se superposer.
Si un signal peut au maximum gérer 16 sorties en parallèle ( combinaison a gogo) alors pouvoir en gérer 2 groupes de 8 serait bien mieux! ( combinaisons. A gogo/2!)
Pousser plus loin decoupage c est ouvrir la boîte de Pandore... mais après tout pourquoi pas... ( ex un 5 deux un 3 feux un 6 feux un 2 feux avec chacun leur ID de base etc... C est ici la modularité maximale... qui me semble trop complexe ( dans un premier temps à construire, voyons cela plus tard
pour une version V2.0)

Il reste encore un peu à mouliner... mais le résultat final sera à la hauteur des efforts!

Encore merci
Laurent

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 495
    • Voir le profil
Re : Levée de boucliers!
« Réponse #24 le: août 17, 2019, 10:53:48 am »
Je retire ce que j'ai dit ! La broche 2 est bien utilisable sur un Nano, après vérification sur le site de référence arduino.cc .

Le choix du type d'Arduino est fait par l'IDE. Rien à faire dans le code par défaut, mais des adaptations aux bonnes broches pourraient être faites.

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 495
    • Voir le profil
Re : Levée de boucliers!
« Réponse #25 le: août 17, 2019, 11:26:05 am »
Un Nano est bien capable de gérer deux feux de 8 leds chacun sans modification. Au delà, il conviendra d'ajouter des multiplicateurs de port, en digital (74HC) ou en PWM (tlc5940)... D'ailleurs, seul un port PWM pourra faire du light dimming (allumage/extinction progressive d'une vieille ampoule), et le Nano ne dispose que 6 broches capables de PWM. Peut être qu'une bibliothèque comme SoftPWM peut rendre ce service...

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 495
    • Voir le profil
Re : Levée de boucliers!
« Réponse #26 le: août 17, 2019, 02:53:09 pm »
Ci-joint mon premier jet de ton projet. Ca fonctionne bien sur mon émulateur, mais je n'ai pas câblé physiquement pour voir le résultat...
Le code de la fin de SignalArduinoPattern::beginSignal() entre balises VISUALSTUDIO m'a servi à tester en balayant à intervalles réguliers toutes les combinaisons actives. Si tu enlèves le #define, tu pourras aussi essayer en vrai ce que ça donne, sans avoir encore le décodage DCC...

laurentr

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re : Levée de boucliers!
« Réponse #27 le: août 17, 2019, 09:13:21 pm »
Bonsoir Thierry

Je viens de jeter un oeil rapidement.
Merci beaucoup. Cela structure bien les éléments déjà en place ou escomptés.

J ai un petit doute pour ce qui est de la valeur dcc+1 pour le second signal...
Car en fait le 1er signal va "bouffer des adresses ( si on part sur 24 etats il en consommera 6 à 4 états ou 12 à 2 états pour les signaux de type H ( moins pour les autres mais la modularite des combinaisons complexe a un impact direct sur les adresses consommées donc pour faire simple on dit que tous les signaux sont de type H et on reserve ainsi le max d adresses possibles.
Si plus tard on est un peu juste alors on pourra regarder pour moduler les affectations au stricte besoin réel des combinaisons à produire ce qui sera un "bon exercice" pour une V2
Dans ce cas précis DCC+1 prendra la valeur DCC de base +5 ou +13 pour la 1ere adresse dispo :) (il me semble)
Reste à voir comment se combinent les adresses et leurs utilisations.

Pour le test grandeur nature il reste donc la partie DCC à intégrer en entrée sur la broche D2 et son traitement pas "la bête"...

le CI est monté
je regarderai cela en fin de weekend/début de semaine

Laurent

« Modifié: août 18, 2019, 10:16:19 am par laurentr »