Couper le code de routine néopixel court
J'ai travaillé sur un indicateur de niveau avec une bande néopixel (WS2812).
Le code est très simple: lire un potentiomètre, cartographier l'entrée et afficher la sortie dans la bande led.
Jusqu'ici tout va bien. Le code que j'inclus ci-dessous fonctionne bien mais, évidemment, laid et répétitif. Étant donné que ma connaissance de la programmation est très faible, je me demande s'il existe un moyen en boucle de raccourcir le code. Veuillez noter que les sept LED ont des couleurs différentes. En fait, c'est le point déroutant pour moi de créer une boucle. Une idée, les gars?
Oui, je sais aussi qu'utiliser autant de retards n'est pas la solution la plus élégante, mais cela ne compromet pas les performances de l'appareil et la barre LED apparaissant est assez agréable.
void leveller () {
int millivolts;
int level;
millivolts = analogRead(A3);
level = map(millivolts, 0, 1024, 0, 7);
if (level <=0){
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
strip.show ();
}
else if ((level > 0)&&(level<1)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
}
else if ((level>= 1)&&(level<2)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
}
else if ((level>= 2)&&(level<3)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
}
else if ((level>= 3)&&(level<4)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
}
else if ((level>= 4)&&(level<5)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(5, 0, 128, 0);
delay(30);
strip.show ();
}
else if ((level>= 5)&&(level<6)) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(5, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(6, 0, 128, 32);
delay(30);
strip.show ();
}
else if (level>= 6) {
strip.clear();
strip.setPixelColor(0, 128, 0, 0);
delay(30);
strip.show ();
strip.setPixelColor(1, 128, 32, 0);
delay(30);
strip.show ();
strip.setPixelColor(2, 128, 64, 0);
delay(30);
strip.show ();
strip.setPixelColor(3, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(4, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(5, 0, 128, 0);
delay(30);
strip.show ();
strip.setPixelColor(6, 0, 128, 32);
delay(30);
strip.show ();
strip.setPixelColor(7, 0, 128, 64);
delay(30);
strip.show ();
}
}
Réponses
Tout d'abord, une petite remarque:
if ((level > 0)&&(level<1))
level est un entier, et il n'y a pas d'entier qui soit à la fois strictement supérieur à zéro et inférieur à un.
if ((level>= 1)&&(level<2))
Il n'y a qu'un seul entier qui vérifie cette condition. Il serait alors plus clair d'écrire
if (level == 1)
Maintenant, pour votre question réelle: une astuce qui fonctionne souvent pour raccourcir le code répétitif consiste à transformer le code en données, à stocker les données dans des tableaux et à les parcourir avec des boucles. Ici, la séquence de couleurs peut être stockée dans un tableau:
const uint8_t colors[8][3] = {
{128, 0, 0},
{128, 32, 0},
{128, 64, 0},
{ 0, 128, 0},
{ 0, 128, 0},
{ 0, 128, 0},
{ 0, 128, 32},
{ 0, 128, 64},
};
Vous pouvez ensuite appeler setPixelColor()dans une boucle qui traverse le tableau. Comme le point final de la boucle dépend du niveau mesuré, il pourrait s'écrire comme ceci:
void leveller() {
int level = map(analogRead(A3), 0, 1024, 1, 9);
strip.clear();
for (int i = 0; i < level; i++) {
const uint8_t *color = colors[i];
strip.setPixelColor(i, color[0], color[1], color[2]);
strip.show();
delay(30);
}
}
Notez que, puisque la sortie de analogRead()est toujours inférieure à 1024, la variable levelsera toujours inférieure à 9, c'est-à-dire qu'elle prendra des valeurs comprises entre 1 et 8 inclus. Et c'est le nombre de couleurs qui seront affichées.