2

Okay, so here is what I'm trying to accomplish:

I have four LEDs, under my fish tank, that I want to fade in and out. I want each LED to fade at a different rate, start at a different "brightness" with PWM, and get a "new" fade-rate every once in a while. Ultimately, it'll make the bottom of the fish tank "pulse" in a "natural" way.

The code I'm using to accomplish this can be found in my GIT repo. There is also a GIF of it "working," there.


Now, here is my problem:

Every once in a while, one of the LEDs (not a specific one) will stop fading and start blinking like a strobe light. I'm not sure what's causing this blinking, since it seems to happen randomly.

The other three LEDs seem to continue to fade in/out while the "bad" LED is spaz-ing out, and it doesn't seem to be isolated to a specific LED. It also doesn't seem to affect only one LED at a time, although it's usually only one LED "blinking" and any given time... but I have seen two going at the same time.

It also doesn't seem to be specific to the "high" or "low" PWM levels, either... it can happen at "bright" levels, "dim" levels, or even in the middle of the fading transition.


Here's what I've tried:

I've tried different Arduino boards, and I've taken the LED count down to a single LED. I've changed variable types from bytes to ints, and back and forth with that tactic. I've been combing through this sketch all day, and I don't see anything that stands out to me as causing the problem.

So, now I'm turning to you all, hoping that someone will be able to see where I've screwed up my code.

Thank you, in advance!


EDIT: Since I've been asked for direct posting of my code, instead of just a link to the source code:

Here is the main .ino file:

#include "led_controller.h"

// Set pin numbers for each LED
byte led1 = 3,
           led2 = 6,
           led3 = 9,
           led4 = 11;

void setup(){
    pinMode( led1, OUTPUT );
    pinMode( led2, OUTPUT );
    pinMode( led3, OUTPUT );
    pinMode( led4, OUTPUT );
}

// Initialize our four classes for our four LEDs
LED a( led1 ),
    b( led2 ),
    c( led3 ),
    d( led4 );

void loop(){
    a.ledChange();
    b.ledChange();
    c.ledChange();
    d.ledChange();

    delay( 60 );
}

And the header file with the class:

// Create our custom LED class
class LED{
    private:
        // Set higest and lowest brightnesses for LEDs
        byte highest = 250,
             lowest = 5;
        byte pin, brightness, isNeg; // Random necessary variables
        int change; // Set the inc/decrement rate for the LED
        int checkNeg(); // See if our change rate is negative, or not
        void changeChange(); // Get a new change rate
    public:
        LED( byte led ); // Define our constructor
        void ledChange ();
};

// Define our constructor
LED::LED( byte led ){
    pin = led;
    changeChange();

    // Set the initial LED brightness by random
    brightness = random( lowest, highest ); 

    // Randomly determine if the LED will start brightening or darkening
    if( random( 1, 2 ) == 1 )
        change *= -1;
}

// Get a new change rate
void LED::changeChange(){
    change = random( 1, 4 );

    if( isNeg )
        change *= -1;
}

int LED::checkNeg(){
    if( change < 0 )
        return 1; // If `change` is negative, return true
    return 0;
}

void LED::ledChange(){
    // Flip LED change value between brightening and darkening
    if( brightness <= lowest || brightness >= highest ){
        change *= -1;

        isNeg = checkNeg(); // Determine if we're brightening/dimming the LEDs

        // A 1-in-25 chance to change the fade-rate
        if( random( 25 ) == 13 )
            changeChange();
    }


    brightness += change; // Adjust the LEDs brightness

    analogWrite( pin, brightness ); // Brighten/darken the LED
}
  • Sounds like integer wraparound to me. – Majenko Dec 31 '17 at 13:21
  • 1
    It sounds like the values you are using for PWM are going outside of the range needed for the fading in and out effect. As part of changing the values, make sure that the value generated for the next setting is within the range for the LED effect that you want to see. I am not sure what library you are using or what PWM settings are being changed or I could be more specific. I am not willing to take the time to peruse your git repository so if you want to update your question with the specific code that generates a new setting, that may be helpful. – Richard Chambers Dec 31 '17 at 13:36
  • I believe I'm staying well between the byte values of 0 and 255. I am just using the regular Arduino analogWrite() function for PWM. – antiDill Dec 31 '17 at 20:14
0

I added some Serial.print() statements to your code to point out the bug:

This is the modified LED::changeLed() function I used:

void LED::ledChange() {

  /**/Serial.print(brightness); 

  // Flip LED change value between brightening and darkening
  if ( brightness <= lowest || brightness >= highest ) {
    change *= -1;

    isNeg = checkNeg(); // Determine if we're brightening/dimming the LEDs

    // A 1-in-25 chance to change the fade-rate
    if ( random (25) == 13 )
      changeChange();

  }


  brightness += change; // Adjust the LEDs brightness

  analogWrite( pin, brightness ); // Brighten/darken the LED

  /**/Serial.print("\t+ ");
  /**/Serial.print(change);
  /**/Serial.print("\t= ");
  /**/Serial.print(brightness);
  /**/Serial.print("\t");
  /**/for (int i = 0; i < (brightness / 5); i++) Serial.print("*");
  /**/Serial.print("\n");
}

I marked the additional lines with /**/.

Here is a piece of the serial monitor output, where the bug occurred. The columns are organised as follows: brightness before the function changed it + change = brightness at the end of this function. The * lines graphically represent the LED brightness (i.e. the last number); this allowed me to run your sketch without a physical LED, at much higher speed (I deleted the delay(60) in loop()).

183        +    3         =    186  *************************************
186        +    3         =    189  *************************************
189        +    3         =    192  **************************************
192        +    3         =    195  ***************************************
195        +    3         =    198  ***************************************
198        +    3         =    201  ****************************************
201        +    3         =    204  ****************************************
204        +    3         =    207  *****************************************
207        +    3         =    210  ******************************************
210        +    3         =    213  ******************************************
213        +    3         =    216  *******************************************
216        +    3         =    219  *******************************************
219        +    3         =    222  ********************************************
222        +    3         =    225  *********************************************
225        +    3         =    228  *********************************************
228        +    3         =    231  **********************************************
231        +    3         =    234  **********************************************
234        +    3         =    237  ***********************************************
237        +    3         =    240  ************************************************
240        +    3         =    243  ************************************************
243        +    3         =    246  *************************************************
246        +    3         =    249  *************************************************
249        +    3         =    252  ************************************************** #####
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    1         =    252  **************************************************
252        +    -1          =    251  **************************************************
251        +    3         =    254  **************************************************
254        +    -3          =    251  **************************************************
251        +    3         =    254  **************************************************
254        +    -3          =    251  **************************************************
251        +    3         =    254  **************************************************
254        +    -3          =    251  **************************************************
251        +    3         =    254  **************************************************
254        +    -1          =    253  **************************************************
253        +    1         =    254  **************************************************
254        +    -1          =    253  **************************************************
253        +    1         =    254  **************************************************
254        +    -1          =    253  **************************************************
253        +    1         =    254  **************************************************
254        +    -1          =    253  **************************************************
253        +    1         =    254  **************************************************
254        +    -1          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -2          =    253  **************************************************
253        +    2         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    1         =    255  ***************************************************
255        +    -1          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************
254        +    2         =    0  
0        +    -2          =    254  **************************************************

The bug begins at the line I marked with ####. I'll try to narrate the events from the point of view of your function, starting from line #### (1):

  1. Is brightness 249 in range? yes -> don't invert sign | add 3 | return
  2. Is brightness 252 in range? no -> invert | change fade rate? yes, new fade rate = ±1 | add -1 (we just inverted the sign) | return
  3. Is brightness 251 in range? no -> invert (here's the bug!) | change fade rate? no | add +1 (ve should subtract, but we just inverted the sign...) | return
  4. It continues like that until a fade rate change occurs, oscillating between 251 and 252. That looks out like a constant brightness.
  5. The fade rate increases and the oscillation values change, maybe approaching 255 (if the smaller value goes below 250 the led will continue to behave properly, but that's not our case).
  6. Another fader rathe change causes the program to make brightness greater than 255 (in our case 254 + 2). And if you add 2 to a one-byte unsigned variable holding a value of 254 you won't get 256 (the variable can't hold that value) but 0. That's something called "integer wraparound", as Majenko pointed out in his comment to your question.

So, that was a long description of a very simple problem. To solve it you cold for instance prevent the brightness value to be greater than 250 and smaller than 5 adding two lines to your ledChange function:

void LED::ledChange(){
    // Flip LED change value between brightening and darkening
    if( brightness <= lowest || brightness >= highest ){
        change *= -1;

        isNeg = checkNeg(); // Determine if we're brightening/dimming the LEDs

        // A 1-in-25 chance to change the fade-rate
        if( random( 25 ) == 13 )
            changeChange();
    }


    /**/ if(brightness > highest) brightness = highest;
    /**/ else if (brightness < lowest) brightness = lowest;

    brightness += change; // Adjust the LEDs brightness

    analogWrite( pin, brightness ); // Brighten/darken the LED
}
  • Holy cow!!! You are absolutely amazing! I have stepped away from this, because I was just getting frustrated, and could NOT figure it out... but you nailed it on the head! I wish I could give you more than just a fake internet point. – antiDill Feb 13 '18 at 2:33

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.