Problem with PWM controlling RGB LED

I have a small project that currently is comprised of a single common cathode RGB LED and a momentary contact push button.

The idea is that the LED will have a number of modes that it can be in (fades, blinks, user defined color, etc,) cycled by the push button.

First I set up the initial mode which fades through a number of colors. That worked nearly perfectly (aside from setting a truly random start color, that still proves tricky.) Next I implemented the button which cycles the device through a number of modes. To test the mode functionality I’ve created 4 modes - the first, fading mode, and then three additional modes, one shows solid red, one solid blue, and one solid green.

Or SHOULD show, I should say. I do get four modes, but for some reason the second mode has odd behavior. Mode 2, which should set the red pin to 255, and blue and green pins to 0 with analogWrite instead shows green fully on, blue at perhaps 50, and red at maybe 20. I’ve tried a number of different settings, all with different results on mode 2, but always wrong!

Here’s my code:

int ledR = D0; 
int ledG = D1;
int ledB = D2;

int buttonPin = A0;
int buttonState = 0;
int lastButtonState = 0;

int currentMode = 1;
int totalModes = 4;

// create 
Fader rFader(ledR, 3);
Fader gFader(ledG, 2);
Fader bFader(ledB, 1);

void setup() {
    pinMode(ledR, OUTPUT);
    pinMode(ledG, OUTPUT);
    pinMode(ledB, OUTPUT);
    pinMode(buttonPin, INPUT);
}

void loop() {
    
    buttonState = digitalRead(buttonPin); // check button's current state
    
    // if button has been pressed, switch to next mode.  If we run out of modes start back at mode 1.
    if (buttonState != lastButtonState) {
        if (buttonState == HIGH) {
            currentMode++;
            if (currentMode > totalModes) {
                currentMode = 1;
            }
        }
    }
    
    lastButtonState = buttonState;
    
    switch (currentMode) {
        case 1:
            rFader.fade();
            gFader.fade();
            bFader.fade();
            delay(50);
        case 2:
            analogWrite(ledR, 255);
            analogWrite(ledG, 0);
            analogWrite(ledB, 0);
        case 3:
            analogWrite(ledR, 0);
            analogWrite(ledG, 255);
            analogWrite(ledB, 0);
        case 4:
            analogWrite(ledR, 0);
            analogWrite(ledG, 0);
            analogWrite(ledB, 255);
    }
    
    
}

I tried debouncin the button, but that wasn’t it. The mode cycling works… I do get four distinct modes. It’s just that for some reason the second mode always seems to behave strangely. I don’t even know where to start with this one! Anyone have any ideas?

I have couple of guesses which may add up to the glitches you observe.

Is it possible the Fader object still controls the LEDs, after you switch modes? Doesn’t it need to be stopped when controlling LED directly using analogWrite()?

Also, is your mode button debounced in hardware? If not, it might generate lots of button presses, rapidly switching your modes. This should not confuse your code, but you basically get random mode after pressing the button. A short (50ms?) delay after detecting the button press is easiest solution (although an “ignore” timeout is better)

1 Like

@natedog, you are missing a “break;” at the end of each case statement!

5 Likes

Derp!

That was definitely it, thank you!

1 Like