Bonjour vincent06160
Je t’ai fait un programme qui démontre l’usage de diodes adressables, de WS2812 dans ce cas, pour en faire des feux de signalisation pour train.
Cela montre surtout la simplicité du câblage par rapport au câblage charlieplexing
, ces LED n’utilisent qu’une pin de l’Arduino (ici la 12 signLedBusPin
).
L’alimentation tel qu’elle est présentée sur ce schéma est possible pour autant que l’on ne pousse pas la luminosité (
brightness
) plus haut que environ
signLebBrightMax = 80
. Si ces LED ne font que de la signalisation ça passe. Si ce type de LED font de l’éclairage, avec une luminosité maximum (
signLebBrightMax = 255
), il faut une alimentation 5V complémentaire.
La définition des feux se fait dans ce tableau :
{feuxSysFrance, 0, "RJV"}, {feuxSysBritanic, 3, "VJJR"},{feuxSysFrance, 7, "RJV"}, {feuxSysBritanic, 10, "VJJR"}
Le premier paramètre donne le type de système (pas encore employé), La première LED du feux et la disposition des couleurs.
Pour la commande des feux, ça se fait par des commandes introduites dans la ligne de commande du moniteur de l’IDE Arduino :
La syntaxe :
FEU001.1.. = feu 1 (de 0 à …), la 2ème LED allumée en jaune puisque la disposition est "VJJR".
Un point dit : LED éteinte. Donc pour éteindre complétement le feux 2 la commande est FEU002…
On peut, bien sûre, allumer plusieurs LED sur un feux :
FEU0031…1, avec une disposition "VJJR", la diode Verte et la rouge seront allumées.
N'importe quel autre système de commandes peut être envisagé.
Les couleurs sont définies dans la fonction void signLedInitialisation()
, ne pas oublier, ce type de LED peut générer environ 16 millions de couleurs.
Le programme :
/*
Name: AF_vincent06160_FeuxTricolores.ino
Created: 29.11.2024
Author: jpbbricole
Remarque: Commande de feux tricolores francais et anglais
https://forum.arduino.cc/t/connexion-charlieplexing/1326015/9
https://chatgpt.com/share/6749eb16-9eec-800a-8f73-46c4070d1f47
*/
#include <Adafruit_NeoPixel.h> // Gestion des LED RGB Neopixel https://github.com/adafruit/Adafruit_NeoPixel
//------------------------------------- LED de signalisation
const int signLedNombre = 50; // Nombre de LED
const int signLedBusPin = 12; // Connexion du bus
const int signLebBrightMax = 70; // LED Luminosité maximum
int signLedNum = 0; // Numéro de la LED
Adafruit_NeoPixel signLed = Adafruit_NeoPixel(signLedNombre, signLedBusPin, NEO_GRB + NEO_KHZ800); // Création de l'objet Neopixel signLed
enum signLedIndex {signLedTypeInfo};
const String signLedColInitial = "RVBJOBX"; // Initiale des couleurs X = tout éteindre
enum signLedColorsIndex {signColRed, signColGreen, signColBlue, signColYellow, signColOrange, signColWithe, signColOff, signColNombre};
uint32_t signLedColors[signColNombre]; // Valeurs RGB pour les couleurs (Tableau)
//------------------------------------- Feux
enum {feuxSysFrance, feuxSysBritanic}; // Système de feux)
const String feuxSysLabel[] = {"Francais", "Britanique"};
struct feuxDef // Définition des paramètres des mpap
{
const int type; // Type francais ou britanique
int ledDebut; // 1ère LED du feux
const String disposition; // Ordre des couleurs RJV pour Rouge en haut, jaune au milieu et vert en bas
};
feuxDef feux[] =
{
{feuxSysFrance, 0, "RJV"}, {feuxSysBritanic, 3, "VJJR"},{feuxSysFrance, 7, "RJV"}, {feuxSysBritanic, 10, "VJJR"}
};
const int feuxNombre = sizeof(feux) / sizeof(feux[0]);
void setup()
{
Serial.begin(115200);
//-------------------------------- LED de signalisation
signLedInitialisation();
//signLedDisplay(signLedNum, signColBlue, 1000);
Serial.println("Systeme de " + String(feuxNombre) + " feux");
//demo();
}
void loop()
{
if (Serial.available()) // Si commande reçue
{
cmdExecute(Serial.readStringUntil('\n')); // Lire jusqu'à nouvelle ligne
}
}
void feuxCommander(String fCmd)
{
Serial.println("Feux commande: " + fCmd);
int feuxNum = fCmd.substring(0, 3).toInt(); // Extraction du numéro de feux (132..1...)
fCmd = fCmd.substring(3); // On garde la commande des feux
fCmd = fCmd.substring(0, feux[feuxNum].disposition.length()); // Pour éviter les débordements
for (int lp = 0; lp < fCmd.length(); lp ++) // Led position sur le feux
{
int feuxEtat = fCmd.charAt(lp) - 48;
feuxEtat = constrain(feuxEtat, 0, 9); // Limiter la valeur de feuxEtat
feuxChanger(feuxNum, lp, feuxEtat);
}
}
void feuxChanger(int fNum, int ledPosition, int ledEtat)
{
int ledNum = feux[fNum].ledDebut + ledPosition;
String colInitiale = feux[fNum].disposition.substring(ledPosition, ledPosition +1); // Extraire la couleur de "RBVRJ" par ex.
int colIndex = signLedColInitial.indexOf(colInitiale);
if (ledEtat != 0) // S'il faut allumer cette LED
{
signLedDisplay(ledNum, colIndex, 0);
}
else // Eteindre la LED
{
signLedDisplay(ledNum, signColOff, 0);
}
}
/*
Commandes depuis le moniteur
Commandes reconnues:
FEU002..1.. pour feu 2 (de 0 à ..) à vert avec disposition = "RBVRJ"
FEU002..1.1 pour feu 2 (de 0 à ..) à vert et jaune avec disposition = "RBVRJ"
FEU002..... pour feu 2 (de 0 à ..) tout éteint
*/
void cmdExecute(String cmdRx)
{
int cmdParInt = 0; // Paramètre integer
cmdRx.trim(); // Nettoyage
cmdRx.toUpperCase(); // En majuscules
cmdRx.replace(" ", ""); // Sans espaces
cmdRx.replace(",", "."); // Pour les décimales
Serial.println("Commande recue: " + cmdRx);
if (cmdRx.startsWith(F("FEU")))
{
cmdRx.replace(F("FEU"), ""); // Ne garder que le paramètre
feuxCommander(cmdRx);
}
else
{
Serial.println("Commande inconnue: " + cmdRx);
}
}
//------------------------------------- LED de signalisation
void signLedDisplay(int ledNum, int colorIndex, int timeDispl)
{
signLed.setPixelColor(ledNum, signLedColors[colorIndex]);
signLed.show();
if (timeDispl > 0) // Si timeDispol > 0 millisec.
{
delay(timeDispl);
signLed.setPixelColor(ledNum, signLedColors[signColOff]);
signLed.show();
}
}
void signLedInitialisation()
{
signLedColors[signColRed] = signLed.Color(255, 0, 0); // Définition des couleurs
signLedColors[signColGreen] = signLed.Color(0, 255, 0);
signLedColors[signColBlue] = signLed.Color(0, 0, 255);
signLedColors[signColYellow] = signLed.Color(255, 255, 0);
signLedColors[signColOrange] = signLed.Color(255, 165, 0);
signLedColors[signColWithe] = signLed.Color(255, 255, 255);
signLedColors[signColOff] = signLed.Color(0, 0, 0);
signLed.begin();
signLed.setBrightness(signLebBrightMax);
signLed.clear();
signLed.show();
}
void demo()
{
cmdExecute("FEU0001..");
//delay(500);
cmdExecute("FEU001.1...");
//delay(500);
cmdExecute("FEU002..1");
//delay(500);
cmdExecute("FEU003...1.");
//delay(1000);
cmdExecute("FEU000...");
cmdExecute("FEU001.....");
cmdExecute("FEU002...");
cmdExecute("FEU003.....");
}
Une simulation:
A ta disposition pour toutes questions.
Cordialement
jpbbricole