Bonjour,
Pour ma part, j'ai compris la philosophie, sauf pourquoi il fallait éviter de mettre les nombres magiques
"Les sept nombres magiques vérifiés expérimentalement sont : 2, 8, 20, 28, 50, 82, 126a (suite A018226 de l'OEIS)."
Autres remarque/question:
D'une part, il y a dans le setup
const int ledPin[] = {10, 11, 12, 13, A0, A1, A2, A3}; // Tableau des pin des LED
//const int ledNombre = sizeof(ledPin) / sizeof(ledPin[0]); // Nombre de LED = nombre d'éléments du tableau calculé à partir du nombre d'octets occupés par l
Et d'autre part, vous écrivez:
Mais il me semble que les 8 élements du tableau sont
ledPin[0]
...
ledPin[7]
et
ledNombre = 8 (de 1 à 8)
Est-ce que je me trompe?
;)
L'expression "nombre magique" est apparue dans le domaine de la programmation dans les années 1960, notamment dans les langages de bas niveau, pour décrire des valeurs numériques qui semblaient surgir "magiquement" dans le code, sans explication apparente.
Ces valeurs étaient souvent utilisées dans les premières étapes de l'informatique pour des configurations matérielles spécifiques, des adresses mémoire, ou des paramètres système, et les programmeurs qui lisaient le code sans connaître la signification de ces nombres pouvaient les percevoir comme des "incantations" mystérieuses.
L'expression "nombre magique" en programmation de nos jours désigne une valeur littérale, souvent numérique, qui apparaît dans le code sans explication ni contexte. Elle est directement insérée dans le code pour que celui-ci fonctionne, mais sa signification ou son origine n'est pas apparente, ce qui rend le code difficile à lire et à maintenir.
L'absence de clarté sur l'origine de ce nombre crée un risque d'erreur si des changements futurs sont effectués (par exemple, ajouter ou retirer une LED ou un bouton dans le cas présent). Pour éviter cela, il est recommandé d'utiliser des constantes nommées et calculées automatiquement si possible, qui rendent l’intention du code explicite et facilitent les modifications ultérieures.
C'est devenu une expression un peu péjorative pour désigner des valeurs non documentées dans le code, qu’il est préférable de remplacer par des constantes explicites pour améliorer la lisibilité et la maintenance du code.
Je me réponds à moi même avec un exemple
// For selon Jef59
int inPin[]={1,2,3,4,5,6,7,8};//8 valeurs
const int ledNombre = sizeof(inPin) / sizeof(inPin[0]);
// --------------------------------------------------------------
void setup(){
Serial.begin(115200);
Serial.print("ledNombre = ");
Serial.println(ledNombre);
for (int i=0; i<ledNombre; i++){
//pinMode(inPin[i], INPUT_PULLUP);
Serial.print("for i = ");
Serial.print(i);
Serial.print(" / inPin[i] = ");
Serial.println(inPin[i]);
}
Serial.println("_______________________");
}
// --------------------------------------------------------------
void loop(){
}
Le but est de voir quelle valeur ou "espace mémoire d'un tableau" va consulter la boucle "for" en commencant par 0.
A voir dans le moniteur série.
0 c'est la première valeur du tableau, et pour un tableau de 8 valeurs, la dernière valeur du tableau c'est celle en position 8-1.
Je n'emploie surement pas les bons termes.
Edit: j'ai amélioré le sketch de ma démo
Sur le moniteur série, je lis
ledNombre = 8
for i = 0 / inPin[i] = 1
for i = 1 / inPin[i] = 2
for i = 2 / inPin[i] = 3
for i = 3 / inPin[i] = 4
for i = 4 / inPin[i] = 5
for i = 5 / inPin[i] = 6
for i = 6 / inPin[i] = 7
for i = 7 / inPin[i] = 8
J'ai donc 8 led numérotée de 0 à 7, et je dois faire une boucle
for (int i=0; i<ledNombre; i++)
Là est l'erreur de @vincentm0911 je crois.
oui les indices d'un tableau en C ou C++ commencent toujours à 0, donc pour un tableau de N éléments, les indices vont de 0 à N-1
Lire (ou pire écrire) en dehors de la mémoire réservée pour le tableau déclenche ce que l'on appelle une "undefined behavior" pour le compilateur. Le code peut faire n'importe quoi ensuite car on a rompu une promesse implicite faite au compilateur qu'on n'irait pas faire des choses en dehors de la mémoire prévue.
Bonjour vincentm0911
L'étape suivante sera de passer aux LED adressables:
Ca simplifie le câblage et ça décuple les possibilités.
Une petite démonstration:
Le programme:
/*
Name: AF_Controle_8_LED_8_boutons_E.ino
Created: 11.11.2024
Author: jpbbricole
Palette: https://www.rapidtables.com/web/color/RGB_Color.html
*/
#include <Adafruit_NeoPixel.h>
//------------------------------------- Définition des interfaces, boutons
struct interfacesDef
{
const int btnPin; // Pin du bouton
unsigned long ledColor;
};
// Rouge vif Bleu vif Vert citron Orange
interfacesDef intf[] = {{2, 0xFF0000}, {3, 0x0000FF}, {4, 0xADFF2F}, {5, 0xFFA500},
// Bleu ciel Gris moyen Rose Rouge foncé
{6, 0x87CEEB}, {7, 0x808080}, {8, 0xFFC0CB}, {9, 0x8B0000}}; // Initialisation des boutons
const int intfNombre = sizeof(intf) / sizeof(intf[0]); // Nombre d'interfaces
const int ledPin = 12; // Pin de données du strip WS2812
const int ledNombre = intfNombre; // Nombre de LEDs dans le strip (une par bouton)
const int ledLuminosite = 150; // Luminosité générale
Adafruit_NeoPixel strip = Adafruit_NeoPixel(ledNombre, ledPin, NEO_GRB + NEO_KHZ800);
int timeDelay = 20; // Delay pour éviter les rebonds du bouton poussoir
void setup()
{
strip.begin(); // Initialisation du strip WS2812
strip.show(); // Éteindre toutes les LEDs au démarrage
strip.setBrightness(ledLuminosite); // Régler la luminosité (0-255)
//--------------------------------- Initialisation des boutons
for (int i = 0; i < intfNombre; i++)
{
pinMode(intf[i].btnPin, INPUT_PULLUP); // Pins boutons en entrée avec pull-up
}
}
void loop()
{
for (int i = 0; i < intfNombre; i++)
{
if (digitalRead(intf[i].btnPin) == LOW)
{
ledAllumer(i); // Allume la LED correspondante
}
}
}
void ledAllumer(int ledNum)
{
for (int i = 0; i < intfNombre; i++)
{
if (i == ledNum) // Si c'est la LED sélectionnée
{
//strip.setPixelColor(i, strip.Color(255, 0, 0)); // Allume en rouge la LED sélectionnée
strip.setPixelColor(i, intf[i].ledColor); // Allume la LED sélectionnée
}
else
{
strip.setPixelColor(i, strip.Color(0, 0, 0)); // Éteint les autres LEDs
}
}
strip.show(); // Met à jour les LEDs pour afficher les changements
delay(timeDelay);
}
A+
Cordialement
jpbbricole
Ok, par inadvertance, je crois que c'est un peu le cas de @vincentm0911
la bibliothèque Adafruit utilise uint32_t (unsigned long) pour représenter les couleurs. Ce n'est pas un "drame" parce qu'il y a une promotion implicite dans la représentation du uint32_t quand on passe un long et qu'une valeur non signée est attendue, mais c'est mieux de prendre le bon type.
Bonsoir J-M-L
Oh que oui!
Merci!
Bonne soirée
jpbbricole
Pour ajouter un détaille à l'explication de @J-M-L, on peut trouver un intérêt de centraliser la valeur de fonctionnement dans des constantes plutôt que des valeurs directement dans des formules ou instructions de contrôle bien documenté.
Car il y a de forte chance que si tu doit modifier ton programme, tu oubli de changer ces valeurs, alors que si celle-ci sont en début de programme, il a plus de chance de ne pas la louper.
oui et encore mieux si on peut la calculer.
par exemple au lieu de faire
const int btnPin[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Tableau des pin des boutons
const int ledPin[] = {10, 11, 12, 13, A0, A1, A2, A3}; // Tableau des pin des LED
et utiliser ensuite 8 dans le code parce que l'on sait qu'il y a 8 éléments dans les tableaux, on pourrait effectivement déclarer des constantes qui valent 8
const byte nombreDeBoutons = 8;
const byte nombreDeLeds = 8;
const int btnPin[nombreDeBoutons] = {2, 3, 4, 5, 6, 7, 8, 9}; // Tableau des pin des boutons
const int ledPin[nombreDeLeds] = {10, 11, 12, 13, A0, A1, A2, A3}; // Tableau des pin des LED
Le compilateur mettra un message si le compte n'y est pas.
Mais le mieux est de calculer cela dynamiquement et cerise sur le gâteau vérifier la cohérence (on doit avoir autant de LEDs que de boutons)
// À CONFIGURER
const byte btnPin[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Tableau des pin des boutons
const byte ledPin[] = {10, 11, 12, 13, A0, A1, A2, A3}; // Tableau des pin des LED
// TAILLES CALCULÉES À LA COMPILATION
const byte nombreDeBoutons = sizeof btnPin / sizeof *btnPin;
const byte nombreDeLeds = sizeof ledPin / sizeof *ledPin;
// VÉRIFICATION DE CONFORMITÉ À LA COMPILATION
static_assert(nombreDeBoutons == nombreDeLeds, "Le nombre de boutons et de LEDs doit être le même.");
Bonsoir,
J'ai eu une carte UNO à prêter pour tester mon programme et j'ai un soucis ![]()
Il semblerait que les PIN 10 11 12 et 13 ne soit pas reconnues comme sorties.
J'ai testé du coup ton programme JPBBRICOLE mais même celui là ne fonctionne pas
Les leds sur A0 A1 A2 A3 s'allument bien, de même, si je branche des leds sur A4 et A5 mais si je déclare sur les sorties 10 à 13 rien ne se passe.
J'ai juste la led L de la carte qui s'allume au lieu de le pin 13.
Je dois avoir un loupé un paramétrage dans IDE mais je ne trouve pas la solution .
Merci de votre aide
Postez le code et le montage utilisé pour cela
Je me réponds à moi même : je pensais avoir trouvé la solution en faisant une mise à jour de la carte sur MBLOCK mais maintenant ce sont les pin A0 à A3 qui ne s'allument pas ...
Je n'y comprends rien.
C'est comme si la carte ne voulait pas allumer plus de 4 leds !!
J'ai TROUVE !!!!!!
J' utilise une vieille carte de prototypage (modèle des années 70 je pense
)
Et sur ma plaque, la ligne de la masse est séparée en 2 au milieu au niveau d'une lettre W.
J'avais testé plusieurs plaques (3 au total) et j'avais forcément le même problème ![]()