Taglio corto del codice di routine neopixel

Oct 23 2020

Ho lavorato su un misuratore di livello con una striscia neopixel (WS2812).

Il codice è molto semplice: leggere un potenziometro, mappare l'ingresso e mostrare l'uscita nella striscia led.

Fin qui tutto bene. Il codice che includo di seguito funziona bene ma, ovviamente, brutto e ripetitivo. Poiché la mia conoscenza della programmazione è molto debole, mi chiedo se esista un modo loop per tagliare il codice breve. Si prega di notare che i sette led hanno colori diversi. In realtà questo è il punto di confusione per me per costruire un ciclo. Qualche idea, gente?

Sì, so anche che usare così tanti ritardi non è la soluzione più elegante, ma non compromette le prestazioni del dispositivo e il led della barra che appare è piuttosto carino.

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 ();
    }
}

Risposte

2 EdgarBonet Oct 23 2020 at 16:30

Innanzitutto, una piccola osservazione:

if ((level > 0)&&(level<1))

level è un numero intero e non esiste un numero intero strettamente maggiore di zero e minore di uno.

if ((level>= 1)&&(level<2))

C'è solo un numero intero che verifica questa condizione. Sarebbe più chiaro quindi scrivere solo

if (level == 1)

Ora, per la tua vera domanda: un trucco che spesso funziona per abbreviare il codice ripetitivo è trasformare il codice in dati, archiviare i dati in array ed eseguirli con loop. Qui la sequenza di colori può essere memorizzata in un array:

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},
};

È quindi possibile chiamare setPixelColor()all'interno di un ciclo che attraversa l'array. Poiché il punto finale del ciclo dipende dal livello misurato, potrebbe essere scritto in questo modo:

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);
    }
}

Si noti che, poiché l'output di analogRead()è sempre inferiore a 1024, la variabile levelsarà sempre inferiore a 9, ovvero assumerà valori compresi tra 1 e 8 inclusi. E questo è il numero di colori che verranno mostrati.