Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - laurentr

Pages: [1] 2 3 ... 15
1
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: février 02, 2023, 09:05:15 pm »
Complément d'info:

La gestion de l'affichage/effacement de l'œilleton est accordé avec la combinaison de chaque feu.

Illustration du montage demo en photo.

On repère bien les 4 fils "uniques" qui vont du Nano Every vers le module SX1509.

La magie opère ensuite pour peu que l'on se projette avec les bonnes couleurs de leds (ici toutes bleues)


Laurent


2
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: février 02, 2023, 06:33:16 pm »
Bonjour

Pour les plus impatients qui voudraient tester un module SX1509 voici un petit programme de demo qui fait changer les états de 2 groupes de 8 leds (2 cibles H) répartis sur les IO0 à 7 puis 8 à 15 de la puce.

///
// TEST SX1509 BREAKOUT BOARD V1.0 31012023 @LTR
///

#include <Wire.h>           // Include the I2C library (required)
#include <SparkFunSX1509.h> //Click here for the library: http://librarymanager/All#SparkFun_SX1509


// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
const byte SX1509_ADDRESS = 0x3E; // SX1509 I2C address
SX1509 io;                        // Create an SX1509 object to be used throughout

// SX1509 Pin definition:
const byte SX1509_LED_16 = 15; // LED to SX1509's pin 15
const byte SX1509_LED_15 = 14; // LED to SX1509's pin 14
const byte SX1509_LED_14 = 13; // LED to SX1509's pin 13
const byte SX1509_LED_13 = 12; // LED to SX1509's pin 12
const byte SX1509_LED_12 = 11; // LED to SX1509's pin 11
const byte SX1509_LED_11 = 10; // LED to SX1509's pin 10
const byte SX1509_LED_10 = 9; // LED to SX1509's pin 9
const byte SX1509_LED_9 = 8; // LED to SX1509's pin 8
const byte SX1509_LED_8 = 7; // LED to SX1509's pin 7
const byte SX1509_LED_7 = 6; // LED to SX1509's pin 6
const byte SX1509_LED_6 = 5; // LED to SX1509's pin 5
const byte SX1509_LED_5 = 4; // LED to SX1509's pin 4
const byte SX1509_LED_4 = 3; // LED to SX1509's pin 3
const byte SX1509_LED_3 = 2; // LED to SX1509's pin 2
const byte SX1509_LED_2 = 1; // LED to SX1509's pin 1
const byte SX1509_LED_1 = 0; // LED to SX1509's pin 0

uint8_t SIGNAL_1_PINS[8] = {SX1509_LED_1, SX1509_LED_2, SX1509_LED_3, SX1509_LED_4, SX1509_LED_5 , SX1509_LED_6, SX1509_LED_7, SX1509_LED_8};

const uint8_t OE_LEVEL = 32;
const uint8_t GREEN_LEVEL = 128;
const uint8_t YELLOW_LEVEL = 100;
const uint8_t YELLOW2_LEVEL = 120;
const uint8_t WHITE_LEVEL = 80;
const uint8_t PURPULE_LEVEL = 120;
const uint8_t RED_LEVEL = 150;

uint8_t SIGNAL_LIGHT_PHASE = 0b11111111;
uint8_t SIGNAL_LIGHT_PHASE2 = 0b11111111;

uint8_t SIGNAL_1_COLOR_LEVELS[8] = {OE_LEVEL, YELLOW_LEVEL, RED_LEVEL, GREEN_LEVEL, RED_LEVEL, WHITE_LEVEL, YELLOW2_LEVEL, YELLOW2_LEVEL};

uint8_t SIGNAL_LIGHT_COMBO_CARRE =  0b00010100;
uint8_t SIGNAL_LIGHT_MODE_CARRE =   0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_CV =     0b00010000;
uint8_t SIGNAL_LIGHT_MODE_CV =      0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_VL =     0b00001001;
uint8_t SIGNAL_LIGHT_MODE_VL =      0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_S =      0b00000101;
uint8_t SIGNAL_LIGHT_MODE_S =       0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_RC =     0b00000101;
uint8_t SIGNAL_LIGHT_MODE_RC =      0b11111011;

uint8_t SIGNAL_LIGHT_COMBO_V160 =   0b00001001;
uint8_t SIGNAL_LIGHT_MODE_V160 =    0b11110111;

uint8_t SIGNAL_LIGHT_COMBO_AV =     0b00000011;
uint8_t SIGNAL_LIGHT_MODE_AV =      0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_JC =     0b00000011;
uint8_t SIGNAL_LIGHT_MODE_JC =      0b11111101;

uint8_t SIGNAL_LIGHT_COMBO_RAL =    0b01000001;
uint8_t SIGNAL_LIGHT_MODE_RAL =     0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_RAL60 =  0b01000001;
uint8_t SIGNAL_LIGHT_MODE_RAL60 =   0b10111111;

uint8_t SIGNAL_LIGHT_COMBO_RRAL =   0b10000001;
uint8_t SIGNAL_LIGHT_MODE_RRAL =    0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_RRAL60 = 0b10000001;
uint8_t SIGNAL_LIGHT_MODE_RRAL60 =  0b01111111;

uint8_t SIGNAL_LIGHT_COMBO_MAN =    0b00100000;
uint8_t SIGNAL_LIGHT_MODE_MAN =     0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_BC =     0b00100000;
uint8_t SIGNAL_LIGHT_MODE_BC =      0b11011111;

uint8_t SIGNAL_LIGHT_COMBO_DISQUE =    0b00000110;
uint8_t SIGNAL_LIGHT_MODE_DISQUE =     0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_AV_RRAL =   0b10000011;
uint8_t SIGNAL_LIGHT_MODE_AV_RRAL =    0b11111111;

uint8_t SIGNAL_LIGHT_COMBO_AV_RRAL60 = 0b10000011;
uint8_t SIGNAL_LIGHT_MODE_AV_RRAL60 =  0b01111111;

uint8_t SIGNAL_LIGHT_COMBO_JC_RRAL60 = 0b10000011;
uint8_t SIGNAL_LIGHT_MODE_JC_RRAL60 =  0b01111101;

uint8_t SIGNAL_LIGHT_COMBO_AV_RAL60 =  0b01000011;
uint8_t SIGNAL_LIGHT_MODE_AV_RAL60 =   0b10111111;

uint8_t SIGNAL_LIGHT_COMBO_JC_RAL60 =  0b01000011;
uint8_t SIGNAL_LIGHT_MODE_JC_RAL60 =   0b10111101;

const uint8_t SIGNAL_LIGHT_COMBO_DUAL_CROSSING = 0b00010100;
const uint8_t SIGNAL_LIGHT_MODE_DUAL_CROSSING =  0b11101011;

uint8_t SIGNAL_LIGHT_COMBO = 0;
uint8_t SIGNAL_LIGHT_MODE = 0;

uint8_t index;

uint8_t SIGNAL_LIGHT_COMBO_LIST[] = {
  SIGNAL_LIGHT_COMBO_VL,
  SIGNAL_LIGHT_COMBO_V160,
  SIGNAL_LIGHT_COMBO_AV,
  SIGNAL_LIGHT_COMBO_JC,
  SIGNAL_LIGHT_COMBO_S,
  SIGNAL_LIGHT_COMBO_RC,
  SIGNAL_LIGHT_COMBO_CARRE,
  SIGNAL_LIGHT_COMBO_CV,
  SIGNAL_LIGHT_COMBO_MAN,
  SIGNAL_LIGHT_COMBO_BC,
  SIGNAL_LIGHT_COMBO_RAL,
  SIGNAL_LIGHT_COMBO_RAL60,
  SIGNAL_LIGHT_COMBO_RRAL,
  SIGNAL_LIGHT_COMBO_RRAL60,
  SIGNAL_LIGHT_COMBO_AV_RRAL,
  SIGNAL_LIGHT_COMBO_AV_RRAL60,
  SIGNAL_LIGHT_COMBO_JC_RRAL60,
  SIGNAL_LIGHT_COMBO_AV_RAL60,
  SIGNAL_LIGHT_COMBO_JC_RAL60,
  SIGNAL_LIGHT_COMBO_DISQUE,
  SIGNAL_LIGHT_COMBO_DUAL_CROSSING
};

uint8_t SIGNAL_LIGHT_MODE_LIST[] = {
  SIGNAL_LIGHT_MODE_VL,
  SIGNAL_LIGHT_MODE_V160,
  SIGNAL_LIGHT_MODE_AV,
  SIGNAL_LIGHT_MODE_JC,
  SIGNAL_LIGHT_MODE_S,
  SIGNAL_LIGHT_MODE_RC,
  SIGNAL_LIGHT_MODE_CARRE,
  SIGNAL_LIGHT_MODE_CV,
  SIGNAL_LIGHT_MODE_MAN,
  SIGNAL_LIGHT_MODE_BC,
  SIGNAL_LIGHT_MODE_RAL,
  SIGNAL_LIGHT_MODE_RAL60,
  SIGNAL_LIGHT_MODE_RRAL,
  SIGNAL_LIGHT_MODE_RRAL60,
  SIGNAL_LIGHT_MODE_AV_RRAL,
  SIGNAL_LIGHT_MODE_AV_RRAL60,
  SIGNAL_LIGHT_MODE_JC_RRAL60,
  SIGNAL_LIGHT_MODE_AV_RAL60,
  SIGNAL_LIGHT_MODE_JC_RAL60,
  SIGNAL_LIGHT_MODE_DISQUE,
  SIGNAL_LIGHT_MODE_DUAL_CROSSING
};



bool bascule = true;

uint32_t currenttime;
uint32_t starttime;
uint32_t starttime2;

//uint8_t SX1509_LED[8] = {SX1509_LED_1, SX1509_LED_2, SX1509_LED_3, SX1509_LED_4, SX1509_LED_5, SX1509_LED_6, SX1509_LED_7, SX1509_LED_8};

//uint8_t SX1509_LED2[8] = {SX1509_LED_9, SX1509_LED_10, SX1509_LED_11, SX1509_LED_12, SX1509_LED_13, SX1509_LED_14, SX1509_LED_15, SX1509_LED_16};

uint8_t SX1509_LED[16] = {SX1509_LED_1, SX1509_LED_2, SX1509_LED_3, SX1509_LED_4, SX1509_LED_5, SX1509_LED_6, SX1509_LED_7, SX1509_LED_8, SX1509_LED_9, SX1509_LED_10, SX1509_LED_11, SX1509_LED_12, SX1509_LED_13, SX1509_LED_14, SX1509_LED_15, SX1509_LED_16};

uint8_t last_index;
bool lock;

//////////////////
//////////////////
//////////////////

void setup()
{
  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
  while (!Serial);
  //delay(1000);
  Serial.println("SX1509 Example");

  Wire.begin();

  pinMode (LED_BUILTIN, OUTPUT);
  digitalWrite (LED_BUILTIN, LOW);

  // Call io.begin(<address>) to initialize the SX1509. If it
  // successfully communicates, it'll return 1.
  if (io.begin(SX1509_ADDRESS) == false)
  {
    Serial.println("Failed to communicate. Check wiring and address of SX1509.");
    while (1)
      ; // If we fail to communicate, loop forever.
  }

  // Use the pinMode(<pin>, <mode>) function to set our led
  // pin as an ANALOG_OUTPUT, which is required for PWM output
  io.pinMode(SX1509_LED_16, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_15, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_14, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_13, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_12, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_11, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_10, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_9, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_8, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_7, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_6, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_5, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_4, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_3, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_2, ANALOG_OUTPUT);
  io.pinMode(SX1509_LED_1, ANALOG_OUTPUT);

  //INIT AT LOW LEVEL EACH CHANNEL:

  io.analogWrite(SX1509_LED_16, 0);
  io.analogWrite(SX1509_LED_15, 0);
  io.analogWrite(SX1509_LED_14, 0);
  io.analogWrite(SX1509_LED_13, 0);
  io.analogWrite(SX1509_LED_12, 0);
  io.analogWrite(SX1509_LED_11, 0);
  io.analogWrite(SX1509_LED_10, 0);
  io.analogWrite(SX1509_LED_9, 0);
  io.analogWrite(SX1509_LED_8, 0);
  io.analogWrite(SX1509_LED_7, 0);
  io.analogWrite(SX1509_LED_6, 0);
  io.analogWrite(SX1509_LED_5, 0);
  io.analogWrite(SX1509_LED_4, 0);
  io.analogWrite(SX1509_LED_3, 0);
  io.analogWrite(SX1509_LED_2, 0);
  io.analogWrite(SX1509_LED_1, 0);

  index = 0;
  last_index = index;
  lock = false;

  //INIT FIRST STATE:
  SIGNAL_LIGHT_COMBO = SIGNAL_LIGHT_COMBO_LIST[index];
  SIGNAL_LIGHT_MODE = SIGNAL_LIGHT_MODE_LIST[index];

  starttime = millis();
  starttime2 = millis();

  Serial.println("Init Done");

}

////////////////////
////////////////////
////////////////////
void loop()
{
  currenttime = millis();

  digitalWrite(LED_BUILTIN, bascule);

  ///////////////
  //SIGNAL 1:
  ///////////////
  for (uint8_t i = 0; i < 8; i++)
  {
    switch (bitRead(SIGNAL_LIGHT_MODE, i)) //SORTIE FIXE ou CLI
    {
      case 1: //SORTIE FIXE
        if (bitRead(SIGNAL_LIGHT_COMBO, i) == 1) //quelle sortie active?
        {
          io.analogWrite(SX1509_LED[i],  SIGNAL_1_COLOR_LEVELS[i]); //allumer selon level
        }
        else
        {
          io.analogWrite(SX1509_LED[i], 0); //eteindre les autres
        }
        break;

      case 0: //SORTIE CLIGNOTANTE

        if (bascule == 1)
        {
          if (bitRead(SIGNAL_LIGHT_COMBO, i) == 1) //quelle sortie active?
          {
            if (bitRead(SIGNAL_LIGHT_PHASE, i) == 1 )
            {
              io.analogWrite(SX1509_LED[i],  SIGNAL_1_COLOR_LEVELS[i]); //allumer selon level
            }
            else
            {
              io.analogWrite(SX1509_LED[i], 0);
            }
          }
        }
        else //(bascule == 0)
        {
          if (bitRead(SIGNAL_LIGHT_COMBO, i) == 1)
          {
            if (bitRead(SIGNAL_LIGHT_PHASE, i) == 1)
            {
              io.analogWrite(SX1509_LED[i], 0);
            }
            else
            {
              io.analogWrite(SX1509_LED[i],  SIGNAL_1_COLOR_LEVELS[i]);
            }
          }
        }
        break;
    }
  }

  /////////////////
  //SIGNAL 2
  ////////////////
  for (uint8_t i = 0; i < 8; i++)
  {
    if (index == 20)
    {
      SIGNAL_LIGHT_PHASE2 = 0b11111011;
    }
    else
    {
      SIGNAL_LIGHT_PHASE2 = 0b11111111;
    }


    switch (bitRead(SIGNAL_LIGHT_MODE, i)) //SORTIE FIXE ou CLI
    {
      case 1: //SORTIE FIXE
        if (bitRead(SIGNAL_LIGHT_COMBO, i) == 1) //quelle sortie active?
        {
          io.analogWrite(SX1509_LED[15 - i],  SIGNAL_1_COLOR_LEVELS[i]); //allumer selon level
        }
        else
        {
          io.analogWrite(SX1509_LED[15 - i], 0); //eteindre les autres
        }
        break;

      case 0: //SORTIE CLIGNOTANTE

        if (bascule == 1)
        {
          if (bitRead(SIGNAL_LIGHT_COMBO, i) == 1) //quelle sortie active?
          {
            if (bitRead(SIGNAL_LIGHT_PHASE2, i) == 1 )
            {
              io.analogWrite(SX1509_LED[15 - i],  SIGNAL_1_COLOR_LEVELS[i]); //allumer selon level
            }
            else
            {
              io.analogWrite(SX1509_LED[15 - i], 0);
            }
          }
        }
        else //(bascule == 0)
        {
          if (bitRead(SIGNAL_LIGHT_COMBO, i) == 1)
          {
            if (bitRead(SIGNAL_LIGHT_PHASE2, i) == 1)
            {
              io.analogWrite(SX1509_LED[15 - i], 0);
            }
            else
            {
              io.analogWrite(SX1509_LED[15 - i],  SIGNAL_1_COLOR_LEVELS[i]);
            }
          }
        }
        break;
    }
  }


  ///////////////////
  //TIMINGS SWAPS:
  //////////////////
  if (currenttime - starttime > 500)
  {
    bascule = !bascule;
    starttime = millis();
  }

  if (currenttime - starttime2 > 8000)
  {
    if (index < 20)
    {
      index++;
    }
    else
    {
      index = 0;
    }

    SIGNAL_LIGHT_COMBO = SIGNAL_LIGHT_COMBO_LIST[index];
    SIGNAL_LIGHT_MODE = SIGNAL_LIGHT_MODE_LIST[index];

    starttime2 = millis();
  }

  ////
  if (lock == false)
  {
    Serial.print("index: ");
    Serial.println(index);

    lock = true;

    Serial.print("SIGNAL : ");
    switch (index)
    {
      case 0:
        Serial.println("VOIE LIBRE");
        break;

      case 1:
        Serial.println("VERT CLI/RAL 160");
        break;

      case 2:
        Serial.println("AVERTISSEMENT");
        break;

      case 3:
        Serial.println("JAUNE CLI");
        break;

      case 4:
        Serial.println("SEMAPHORE");
        break;

      case 5:
        Serial.println("ROUGE CLI");
        break;

      case 6:
        Serial.println("CARRE");
        break;

      case 7:
        Serial.println("CARRE VIOLET");
        break;

      case 8:
        Serial.println("MANOEUVRE");
        break;

      case 9:
        Serial.println("BLANC CLI");
        break;

      case 10:
        Serial.println("RAL30");
        break;

      case 11:
        Serial.println("RAL60");
        break;

      case 12:
        Serial.println("RAPPEL RAL30");
        break;

      case 13:
        Serial.println("RAPPEL RAL60");
        break;

      case 14:
        Serial.println("AVERTISSEMENT + RAPPEL RAL30");
        break;

      case 15:
        Serial.println("AVERTISSEMENT + RAPPEL RAL60");
        break;

      case 16:
        Serial.println("JAUNE CLI + RAPPEL RAL60");
        break;

      case 17:
        Serial.println("AVERTISSEMENT + RAL60");
        break;

      case 18:
        Serial.println("JAUNE CLI + RAL60");
        break;

      case 19:
        Serial.println("DISQUE");
        break;

      case 20:
        Serial.println("PN");
        break;
   
    }
   
  }


  if (last_index != index)
  {
    lock = false;
    last_index = index;
  }

  ////


}

La rotation s'effectue toutes les 8 secondes et la fréquence de 1Hz effectue donc un changement d état pour les signaux clignotant toutes les 500ms ( estimatif car non base sur une interruption hardware d'un TIMER)

Une piste d'amélioration :)

edit: ajout fonction de suivi des états sur le moniteur série


Laurent

3
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: février 01, 2023, 03:26:50 pm »
Et bien en fait nous avons déjà une partie de ce que je pense être "une bonne réponse":

Nous savons que les incrémentations  d'affichage PWM doivent se faire en parallèle OU si on recompose l'équation cela se traduit par: pour chaque couleur de canal on fait varier à une vitesse différente la même incrémentation dans un rapport de vitesse disons de 1 à 8. ( nos 8 fameuses couleurs !!)

On en vient donc à l'idée d'utiliser un "timer" dont le rôle va être d incrémenter à intervalle fixe une valeur tous les x temps. Pour chaque couleur on rythme l'incrémentation en fonction du décompte de ce timer et on a alors la variation de la valeur PWM de chaque canal de temps

Il nous restera juste à nous assurer alors que notre temps d intervalle soit lui le multiple le plus proche de 8 qui nous intéresse.

Et si deux couleurs différentes doivent varier à la même vitesse finalement? Simple, elle auront alors les mêmes compteurs de bascule d'incrément.
En revanche si le rapport 1 à 8 est insuffisant? Et bien comme le dit une célèbre pub "patron on est mal! ?? Pas tout à fait car nous avons fixé ce rapport librement et arbitrairement il nous faudrait alors le revoir et l'ajuster

L'approche j en conviens n'est pas des plus simple! Si  parmi vous d autres on des idées pour "solutionner" je suis preneur.

@Trimarco232, qu'en penses tu? Tu es le plus avancé d entre nous sur le sujet "pilotage de signaux", ceci te parait il être une "bonne méthode" ou faut il finalement aller au plus simple...? ( via les PIN capable de faire du "BREATH" uniquement? ( alternative "simplissime" :) )

Pour les plus curieux voici un bel article (en anglais) qui illustre l utilisation du SX1509:

https://learn.sparkfun.com/tutorials/sx1509-io-expander-breakout-hookup-guide#-example-digital-inout-and-pwm

A vos avis!?

Laurent

4
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: février 01, 2023, 03:01:11 pm »
Bonjour

J ai un peu avancé dans la trame du code de pilotage des différents aspects du signal.

Pour le moment j ai un effet ON/OFF très acceptable visuellement de chaque led selon la combinaison de leds que je désire voir s'afficher ( en fixe ou clignotant avec pour chaque couleur un niveau d intensité lumineuse pré réglable)

Pour pousser plus loin l'effet visuel  simulant la montée/descente  progressive de l'intensité lumineuse d'une AMPOULE INCANDESCENTE sur une LED il faut donc jouer de la "PWM".

Jusque la tout va bien le "analogWrite" qui va bien va nous aider.

Chaque led va donc via l incrémentation de la valeur PWM confiée à "analogWrite" faire varier progressivement l'intensité lumineuse jusqu'au seuil haut désiré dans la plage [0;255] que supporte notre SX150X.

Si cette incrémentation est IDENTIQUE pour chaque cycle et chaque canal nous allons avoir un "loupé" .Les leds vont avoir des niveaux d'intensité lumineuse différents selon leur couleur d affichage.

Le seuil haut ( niveau désiré d éclairage de la led) d une led verte aura par exemple une valeur de 120 et une rouge sera à 80 ( valeurs arbitraires pour illustrer)

On va donc avoir la led ROUGE qui aura atteint son intensité désirée avant celle de la verte qui doit continuer de s'incrémenter.
Hors les combinaisons lumineuses quelque soient les couleurs affichées doivent être synchrones entre le niveau 0 et leur seuil haut d'intensité lumineuse désirée.

Même si les temps sont extrêmement brefs j ai peur que ce "décalage" soit "visuellement disgracieux" si perçu.

Une solution est de mixer la valeur des résistances de chaque canal avec la couleur de la led à allumer. On perd la flexibilité de mapping mais on simplifie le code. ( et le hard n'est plus  identique en terme de valeur de résistance avec chaque led associée sur le canal)
C est une première option.

Une autre option est que pour un intervalle de temps donné (disons 500 ms pour illustrer) on incrémente selon la couleur une valeur différente chaque changement de  niveau d'intensité. On grimpe par exemple de 3 en 3 pour une verte la ou on grimpe de 1 en 1 pour une rouge.
Cette option séduisante sur le papier se heurte au pragmatise du code. En effet on doit passer en valeur des bytes ( uint8_t) ( donc des nombre entiers) compris entre 0 et 255. Pas le droit d utiliser des float ou alors il faut les remapper ( via fonction map par exemple) en entier et on va se retrouver in fine avec un décalage ( très réduit) de l'atteinte des seuils.

L'effet visuel disgracieux est réduit mais encore présent ( reste t il toutefois réellement bien perceptible?)

Finalement une petite combinaison de multiples pour les différents seuils lumineux par couleur de manière pré établie dans cette logique aurait peut être vocation à nous sortir de l'embarras en apportant la souplesse attendue.

Traduction on incrémente la valeur qui pilote la couleur ayant le rendu lumineux le plus intense pour un même niveau de PWM le moins vite possible et inversement, la couleur ayant le rendu le moins intense pour un même niveau de PWM s'incrémente moins souvent mais avec une valeur d'incrémentation plus forte et proportionnelle.

Ainsi pour chaque cycle d'incrémentation de la valeur de PWM par ajout/soustraction d un pas selon la couleur permet de grimper de 0 à 255 avec un fondu visuel similaire quelque soit la couleur de chaque sortie.

Est ce assez astucieux? Sur le papier je dirai que oui. Revenons cote encodage de cela.
Nous avons "7 combinaisons de couleurs par usage": ( 8 si on considère l'intensité du deuxième feu du carré différente de celle du feu rouge du sémaphore)
BLANC pour l'œilleton
BLANC pour la manœuvre
VIOLET carré violet
ROUGE ( intensité pour feux Sémaphore et carre et confondus sinon ROUGE S et ROUGE C)
VERT
JAUNE 1 feux
JAUNE pour 2 feux en PARALLELE

convertit en multiples nous aurions les valeurs 1 7 14 21 28 35 42.

Se méfier des fausses bonnes idées puisque on va vite se rendre compte que 255/42 va en gros nous laisser 5 paliers au plus entre le 100/100 allume et le 100/100 éteint. ( max/min de l'intensité possible) Hors nous seront en chemin vers celle ci et il faut aussi ne pas la dépasser. Coté progressivité c est "saccadé" et donc contraire au but recherche.

Alors que reste t il comme solution(s)?

5
Vos projets / Re : Micro centrale DCC
« le: janvier 30, 2023, 09:18:14 pm »
Bonsoir

Expliqué ainsi je comprends mieux les enjeux et choix qui en découlent.

Donc pour de l'information courante "non prioritaire" on peut dire OK c est suffisant via I2C, pour une info devant être "de premier ordre"  (type détection de cour circuit par exemple dont on va vouloir exploiter le plus rapidement possible une réaction rapide) ce n est pas le plus adapté pour x raisons.

Merci
Laurent

6
Vos projets / Re : Micro centrale DCC
« le: janvier 30, 2023, 03:44:47 pm »
Bonjour

Une question de nouveau sur les modules IC2 de détection de tension/courant.

J ai cru comprendre que vous indiquez que le "analogread" sur les IO A0 et A1 serait plus "performant" ( rapide) avec en front un INA139 /INA169 ou un LM358 que le transfert des info sur le bus I2C via par exemple un INA219.

D où la question sous jacente, si c est si "lent en I2C" pourquoi a t on alors des modules de mesure sur cette techno ( INA 219) si c est si peu "performant"...

J essaye juste de comprendre ce qu'il est préférable d utiliser ( si on a pas assez de pin Analogread alors l I2C est un backup certes mais sinon...? ) Faut il systématiquement privilégier l approche "classique ( LM358, INA 1x9??)

Comment faire ce choix en connaissance de cause?


Laurent

7
Vos projets / Re : Micro centrale DCC
« le: janvier 25, 2023, 11:26:31 am »
Hello

Dominique, puisque tu évoques cette notion de rapidité de lecture/traitement d une information je m interroge sur la rapidité de traitement d une info telle que remontée ici par l ampli op et traitée via la lecture des entrées An et la remontée d une info similaire sur un bus I2C comme avec un INA219 ou un INA3221 plutôt que par un INA169 ( équivalent de notre montage en LM358...)

Qu est ce qui parait être le plus rapide/efficace?
L I2C offre un gain de PINOUT toujours utile, présente t il d'autres avantages ( moins sujet aux perturbations?) ou inconvénients ( plus lent finalement?) donc contraire au but recherché?

Des avis?

Laurent

8
Vos projets / Re : Micro centrale DCC
« le: janvier 25, 2023, 09:59:56 am »
Bonjour

Merci
Explique ainsi c est parfait.

Si je posais le cadre c est pour une question simple d une application que j ai en tète: le auto sens de phase entre booster differents ou la gestion de boucle de retournement ( type LENZ LK200)
 qui repose sur le principe d une détection très rapide de court-circuit pour une inversion de phase

Alors oui une mesure de courant ou de consommation n est peut être pas directement exploitable mais je m interroge sur ce qui peut être exploité pour parvenir a ce mode de fonctionnement très utile.

Laurent

9
Vos projets / Re : Micro centrale DCC
« le: janvier 24, 2023, 11:55:13 pm »
Bonsoir

Merci pour les info autour de l'ampliOP.

Si je pose en condition Vmax sur une entrée de CPU = 3V3 ( comme sur un ESP32 par exemple) alors que devient notre montage?
J extrapole donc:
On modifie le rapport du gain afin de ne pas dépasser 3V3? (donc le COEF doit être augmenté?)

On garde 0.1r en résistance de mesure pour garder 0.1V/A
Si on la modifie quel impact ( on chauffe, on a un rapport diffèrent entre delta V et A...?)

Par ailleurs comment déterminer la puissance optimale de cette résistance de 0.1r ( applique t on u²/r ? ) et comment calculer l élévation de température dessus ( je suis toujours soucieux de ne pas mettre en œuvre des radiateurs…)

C est peut être un peu basique mais ca permet de bien comprendre tout le mécanisme et de pouvoir l'exploiter dans d autres montages.

Laurent

10
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: janvier 24, 2023, 04:52:07 pm »
Mais ou veut il en venir?...

J arrive, j arrive!

En utilisant la librairie d'AIKO PRA :
https://github.com/aikopras/AP_DCC_library

et en regardant ce qui est fait dans le "decoder-core":
https://github.com/aikopras/AP_DCC_Decoder_Core

On voit que la gestion des adresses et des sorties est déjà en place. Il restera à configurer les décodeurs selon le type de trame qu il va recevoir ( ROCO , LENZ, ...)

La plage d adresse du décodeur va donc selon les besoin propre à chaque signal être soit un groupe de 5 adresses contiguës ( cas pour une cible H (8 feux) ) soit une variation de ceci selon le remplissage "matriçage" cible d'optimisation en sorties ou en adresses ( ou des deux!)

Tout le monde suit toujours?


11
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: janvier 24, 2023, 03:53:49 pm »
Bonjour

Poursuite des préparatifs

La gestion des commandes décodeurs d accessoires répond selon des déclinaisons du protocole DCC ( 9bits mode basic , 11bits mode "Extended") et selon les fabricants de centrale ( ROCO, LENZ...)

Une centrale comme la DR5000 pilote chaque sortie individuellement en mode "Extended" selon 2 états ( ROUGE/ VERT) et offre 2048 items x2 choix : rouge ou vert = 4096).

Une centrale come la LENZ LH100 passe elle par un mode d adressage basic ( adresses de 0 à 511) avec 4 états possibles d'ou 512 x4 x 2 états possibles par sortie  = 4096.

C est la gestion interne du décodeur qui devra "aiguiller" ensuite vers les sorties à piloter. (ON OFF, fading...) selon la combinaison que l'on désire afficher.


Se pose alors une double problématique.
Veut on économiser sur les sorties (PIN OUT et leur affectation à l'attribution de la gestion d'une couleur de feu? ( chaque puce SX1509 offre 16 sorties. contre 8 pour les SX1508)
Veut on économiser le nombre d adresses de base et/ou de sorties pilotées pour exploiter par exemple toutes les PIN OUT des puces SX sans en laisser sans affectation.

Ces questionnements simples sont pourtant des axes important d' implémentation.

Une analyse simple et directe peut être de repartir de la cible H avec toutes les combinaisons qu'elle peut présenter et y ajouter celle du disque.

On à alors:

Pilotage physique de 8 canaux pour les leds ( blanc, rouge, jaune vert  ou violet) selon toutes les combinaisons possibles.
5 adresses de bases consommées
10 OUTPUTS de 2 états

Si les besoins sont inferieurs on saute jusqu' au slot dispo suivant et les ressources sont "perdues" par auto consommation ou à affecter avec soins par ailleurs. (pour un aiguillage par exemple)

Exemple on affecte la première adresse à 120 ( adresse de base), on consomme alors 5 adresses en mode basic soient les adresses supplémentaires 121 122 123 et 124 qui avec la 120 donnent bien 5 adresses contiguës.
Dans le cas d'affectation directe des sorties nous auront alors à activer les OUTPUTS portant les numéros allant de 477 à 496. ( selon la formule ( Sortie = (Addresse-1)*4 + n  avec n=[1;4] )

Si on n'utilise pas  certaines combinaisons alors on peut re affecter leur usage pour d autres accessoires mais cela IMPOSE un RIGUEUR dans la gestion des ressources ou votre ami "EXCEL" sera de mise.

Le tableau suivant illustre cette implémentation.



12
Vos projets / Re : Micro centrale DCC
« le: janvier 24, 2023, 02:55:35 pm »
Bonjour

J'ai pris le temps de regarder le montage avec soin.

Peut etre ajouter un condo de decouplage de 100nF sur l entrée d alim de l ampli OP ne fera pas de mal.
Je pinaille!

Mais quelques questions malgré tout:

Pourquoi faire une lecture sur A0 ET A1? ( portabilité?)

Pourrait on avoir "la formule qui va bien" pour:

Définir une valeur de R ( et la puissance à calibrer pour celle ci) , un seuil V d alim ( 12 24 )  et un intensité I ( disons de 0,5 à 5) et la correspondance en lecture sur les entrées An.

Cela favorisera une réutilisation éventuelle ultérieure.


Enfin une idée " à creuser" serait la mise en parallèle de plusieurs "mini centrale" afin de gérer des cantons ou des "portions" de réseau: comment synchroniser les ponts en H qui sont alors en parallèle les uns avec les autres...?

Laurent




13
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: janvier 22, 2023, 08:57:17 pm »
Gestion des feux clignotants:

Il y a une bascule entre 2 états:

Celui ou tout est allume VERSUS, celui on un certain nombre de feux est éteint et réciproquement

Le passage d'un état vers l'autre se fait via un fondu visuel appelé "FADING".

Cela se traite par un variation du PWM. ( simplement via la commande ANALOGUEWRITE en incrémentant la valeur du PWM entre deux seuils à une vitesse plus ou moins rapide).

Nous pouvons variabiliser ces éléments et les rendre modifiables via CV ou une IHM.

14
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: janvier 22, 2023, 08:44:33 pm »
Les blocs de traitement vont donc être:

  • MAPPER les adresses DCC et les états à afficher
  • GERER l'intensité lumineuse : de MINIMUM (0) à MAXIMUM (255) ou a un LEVEL déterminé
  • PASSER d'une intensité lumineuse à une autre
  • BASCULER d'un état à un autre
  • PILOTER les sorties correspondantes de puces I2C




15
Vos projets / Re : SIGNAUX: CIBLES ET DECODEURS
« le: janvier 22, 2023, 06:53:28 pm »
Poursuivons:

Nous allons poser quelques règles de conception.

L'usage des puces SX1508 et S1509 ouvre la possibilité de travailler sur les IO en 3V3 ou  5V.
Par simplification nous allons travailler en 3V3. (ce qui nous évite 1 fils supplémentaire)
Ceci va donc IMPOSER de monter en parallèle les leds car lorsque 2 seront requises dans des combinaisons de RAL et RRAL car  la tension y serait insuffisante.

Autre règle: nous pourrions utiliser la possibilité HARDWARE de la gestion du "breathe" pour l allumage te l extinction progressive des led sur des broches dédiées.

Au maximum 8 le sont sr le SX1509 et uniquement 4 sur le SX1508.

Si cela couvre les besoins de nos signaux de base, l ajout d ID ou de TID n'offrira alors pas cette possibilité. Idem pour le cas de potences ou les multiples combinaisons seraient restreintes.

Nous aurons donc un peu plus de lignes de code à traiter pour des mouvement de luminosité par variation du PWM lui dispo sur chaque IO.

A ce stade je m'interroge sur le mode de mise en œuvre/mise en service: gestion FULL CV ou via "IHM"?

La solution type "ACROMORA" est séduisante, simple, efficace. C'est une piste. L'autre est une gestion d accessoires classiques via une (interminable) liste de CV.

Vos avis sont les bienvenus pour statuer sur l'une ou l'autre des orientations à donner.

Pages: [1] 2 3 ... 15