RDG LED cycle on and off with button

Hi Everyone,
I am brand new to Arduino and am trying to set up an RGB Led to cycle through colors when I press a button and then stop when I press the button again. So far, I have gotten the light to cycle when I press a button, but it only cycles through the colors once and then settles on red. To turn it off, I have to wait until the cycle completes for the button press to register and turn off the LED.
I would like to be able to turn on the cycle as soon as I press the button as for the cycle itself to keep repeating rather than only shifting through the colors once.
Any help on my code would be appreciated.

const int  greenPin = 5;   // Green LED pin
const int  bluePin = 2;   // Blue LED pin
const int buttonPin = 11; 
boolean lastButton = HIGH; // HIGH is the not pressed state
boolean currentButton = HIGH;
boolean ledOn = false;
int counter = 0;
const int maxBright = 225; // Maximum LED brightness

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600); // starts serial communication 
pinMode (redPin, OUTPUT); // sets the digital pin to output 
pinMode (greenPin, OUTPUT);
pinMode (bluePin, OUTPUT);
pinMode (buttonPin, INPUT_PULLUP); //define pinMOde and use Pull-up resister
serialOut(ledOn, counter); //write the initial state of the LED
}

void setColor(int redValue, int greenValue, int blueValue){
    analogWrite(redPin, redValue);
    analogWrite(greenPin, greenValue);
    analogWrite(bluePin, blueValue);
}

void loop() {
  // put your main code here, to run repeatedly:
 int longDelay = 1000;   // fading time between colors
 int shortDelay = 10;    // short time delay between colors
 int redValue;
 int greenValue;
 int blueValue;
 int ledGear;

currentButton = debounce(lastButton);

if(lastButton == LOW && currentButton == HIGH){
  counter += 1;
  ledOn = !ledOn; // shorthand way to switch to the opposite setting
if (ledOn == true){ 
  Serial.print("Cycling RGB");
  redValue = maxBright;
  greenValue = 0;
  blueValue = 0;
  ledGear = 1;
  do {
        setColor(redValue, greenValue, blueValue);
        //First Gear - Fade from Red to Green
        if (ledGear == 1) {
            redValue -= 1;
            greenValue += 1;
        }
        //Second Gear - Fade from Green to Blue
        if (ledGear == 2){
            greenValue -= 1;
            blueValue += 1;
        }
        //Third Gear - Fade from Blue to Red
        if (ledGear == 3){
            blueValue -= 1;
            redValue +=1;
        }
        //Gear Switching
        if (greenValue == maxBright) ledGear = 2;
        if (blueValue == maxBright) ledGear = 3;
        if (redValue == maxBright+1) ledGear = 4;
        delay(shortDelay); 
      
    } while (ledGear < 4);
    
    }
    if (ledOn == false){
     digitalWrite(redPin, ledOn);
     digitalWrite(greenPin, ledOn);
     digitalWrite(bluePin, ledOn);
    }
  serialOut(ledOn, counter); //write state of the LED and the number of times pushed 
  
}
  lastButton = currentButton;  
}

// Deboucing function 

boolean debounce(boolean last){
  boolean current = digitalRead(buttonPin);

  if(last != current){
    delay(5);
    current = digitalRead(buttonPin);
  }
  return current;
}

//printing function
void serialOut(boolean ledState, int i){
  Serial.print("LED is");
  if (ledState) Serial.print("ON - pressed");
  if(!ledState) Serial.print("OFF- pressed");
  Serial.print(i);
  Serial.println(" times");
}

type or paste code here

You are missing a const int redPin = ??;

const int redPin = 4;
const int greenPin = 5; // Green LED pin
const int bluePin = 2; // Blue LED pin
const int buttonPin = 11;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // starts serial communication
  pinMode (redPin, OUTPUT); // sets the digital pin to output
  pinMode (greenPin, OUTPUT);
  pinMode (bluePin, OUTPUT);
  pinMode (buttonPin, INPUT_PULLUP); //define pinMOde and use Pull-up resister
}

void setColor(byte redValue, byte greenValue, byte blueValue) {
  analogWrite(redPin, redValue);
  analogWrite(greenPin, greenValue);
  analogWrite(bluePin, blueValue);
}

void loop() {
  static int HUE = 0;

  if (digitalRaed(!buttonPin)) {
    HUE += 5;
    if (HUE >255){
      setColor(0, 0, 0);
      HUE = -5;
    }
    else if (HUE < 85)setColor( 255 - HUE * 3, 0, HUE * 3);
    else if (HUE < 170)setColor(0, (HUE-85) * 3, 255 - (HUE-85) * 3);
    else setColor((HUE-170)* 3, 255 - (HUE-170)* 3, 0);
    delay(20);
  }
}

oops, I do have one! I think it might not have copied over. ---- const int redPin = 3; ----- Thanks for the catch

Thanks for the code that shows another way to cycle through colors. - but the button still seems to have no effect. Any idea why or how to add that functionality in?

if (!digitalRead(buttonPin)) {

oops.

2 Likes

Check your RGBLED for Common Cathode (COM to GND) or Common Anode) COM to VCC)

https://wokwi.com/projects/368899956761669633

Your original code works (first, add redPin)

1 Like

:crazy_face: :smile:

Your code works, too, @kolaha

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.