1

I've been working on a level meter with a neopixel strip (WS2812).

The code is very simple: reading a potentiometer, mapping the input and showing the output in the led strip.

So far, so good. The code I include below is working fine but, obviously, ugly and repetitive. Since my knowledge of programming is very weak, I wonder if there is any loop way to cut the code short. Please note that the seven led have different colours. Actually this is the confusing point for me to build a loop. Any idea, folks?

Yes, I also know that using so many delays isn't the mos elegant solution, but it does not compromise the device performance and the bar led appearing is quite nice.

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 ();
    }
}
  • simplest reduction .... do not repeat code unnecessarily .... you have if a>0 do x ... else if a>1 do x,y ... else if a>2 do x,y,z ......... instead do if a>0 do x ... if a>1 do y ... if a>2 do z – jsotola Oct 23 '20 at 17:58
2

First, a small remark:

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

level is an integer, and there is no integer that is both strictly larger than zero and smaller than one.

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

There is only one integer that verifies this condition. It would be clearer then to just write

if (level == 1)

Now, for your actual question: one trick that often works to shorten repetitive code is to turn code into data, store the data in arrays and run through them with loops. Here the sequence of colors can be stored in an 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},
};

You can then call setPixelColor() within an loop that runs through the array. As the end point of the loop depends on the measured level, it could be written like this:

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

Note that, since the output of analogRead() is always smaller than 1024, the variable level will always be smaller than 9, i.e. it will take values between 1 and 8 inclusive. And that is the number of colors that will be shown.

  • Brilliant! It worked fine at the first try. Thank you so much for your programming lessons. Best regards from Spain. – Vidal Oct 23 '20 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.