Issues using a NO push button to start/stop RGB transition

So in a nutshell the idea behind the project is to press the button, have the RGB transition start and run continuously until the button is pressed again. Then it stays off until the button is pressed again. I’ve gone through the debounce example, other button examples and have done some research online. Including on the arduino forums and reddit. The problem is that the RGB transition starts right after the device is plugged in and the button doesn’t work unless the arduino reset button is pressed. At that point it will start by the press of the button but won’t stop when the button is pressed again.

I could really use some help flushing this out because I’ve been fighting with it for awhile now. Thank you in advance for any advice. :slight_smile:

I’m using common anode RGB LEDs on an arduino nano with ATMega 328 and a NO momentary push button.

const int redPin = 3;
const int greenPin = 6;
const int bluePin = 5;
const int buttonPin = 10;
const int ledPin = 7;

void setup() {
  // Start off with the LED off.
  pinMode(buttonPin,INPUT);
  pinMode(ledPin,OUTPUT);
  while(digitalRead(buttonPin)==LOW){}
  setColourRgb(0,0,0);
}

void loop() {
  digitalWrite(ledPin, HIGH);
  unsigned int rgbColour[3];

  // Start off with red.
  rgbColour[0] = 255;
  rgbColour[1] = 0;
  rgbColour[2] = 0;  

  // Choose the colours to increment and decrement.
  for (int decColour = 0; decColour < 3; decColour += 1) {
    int incColour = decColour == 2 ? 0 : decColour + 1;

    // cross-fade the two colours.
    for(int i = 0; i < 255; i += 1) {
      rgbColour[decColour] -= 1;
      rgbColour[incColour] += 1;
      
      setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
      delay(5);
      
    }
    
}
  }

void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}

Lighting_ino.ino (1.01 KB)

Welcome azent.

Do you think you should read buttonPin somewhere else other than setup() ;)

That was something I found on reddit while i was beating my head against the wall, I should’ve known better :slight_smile: . I have gone back and have tried to just combine the RGB transition code I had found with the Debounce example from the IDE.

The debounce example alone was working with my button correctly and the RGB code works with the rest of the circuit correctly. The button I am using has a built in led so I used that for the led in the example.

Problem is now I get these errors.

Lighting_ino.ino: In function ‘void setup()’:
Lighting_ino:15: error: ‘setColourRgb’ was not declared in this scope
Lighting_ino.ino: In function ‘void loop()’:
Lighting_ino:51: error: ‘setColourRgb’ was not declared in this scope
Lighting_ino:59: error: a function-definition is not allowed here before ‘{’ token

I have looked through the code a few times and can’t seem to find any unbalanced ‘{’ or ‘}’ so I am not really sure where I am going wrong. When I try to declare it before setup() I get errors as well.

Here is the updated code

const int redPin = 3;
const int greenPin = 6;
const int bluePin = 5;
const int buttonPin = 10;
const int ledPin = 7;

int ledState = HIGH;         
int buttonState;             
int lastButtonState = LOW;
long lastDebounceTime = 0;
long debounceDelay = 100;

void setup() {
  // Start off with the LED off.
  setColourRgb(0,0,0);
  pinMode(buttonPin,INPUT);
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin, ledState);
}

void loop() {
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  } 

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
        ledState = !ledState;


        unsigned int rgbColour[3];


        // Start off with red.
        rgbColour[0] = 255;
        rgbColour[1] = 0;
        rgbColour[2] = 0;  

        // Choose the colours to increment and decrement.
        for (int decColour = 0; decColour < 3; decColour += 1) {
          int incColour = decColour == 2 ? 0 : decColour + 1;

          // cross-fade the two colours.
          for(int i = 0; i < 255; i += 1) {
            rgbColour[decColour] -= 1;
            rgbColour[incColour] += 1;

            setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
            delay(5);

          }

        }


        void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
          analogWrite(redPin, red);
          analogWrite(greenPin, green);
          analogWrite(bluePin, blue);
        }
      }
    }
  }
  digitalWrite(ledPin, ledState);
  lastButtonState = reading;
}

and can't seem to find any unbalanced '{' or '}' so I am not really sure where I am going wrong

Click the cursor after the opening brace and the matching closing brace is highlighted.

When I try that with the code you posted for the start of the loop function then the matching brace is the last one in the code. So you are still missing the unmatching one.

See if you can find it now with this tool.

Wow what a lot you have missed. The loop function must be finished before you declare the setColourRgb function. So you have 6 missing closing braces in the loop function and four too many in the setColourRgb function.

Then you have to cope with the fact that the "reading" variable is not declared in the setColourRgb function.

Thank you both for your help. I am in better shape now but I’m still having a couple problems I don’t quite understand.

The first problem is that the led transitions through the spectrum once and then stops. It stays lit but only on the last color.

Second, the button works properly to start the program but will not stop the program. However, each time the transition stops, pressing the button will restart the transition. Also, the led built into the button turns on and off as it should.

I know that the void loop() should run over and over indefinitely so I’m unsure what is halting the transition. The button itself appears to be working properly but I cant figure out why I cannot turn the RGB leds off.

Should there be another IF statement in there somewhere that executes if the button’s state is low?

Here’s the latest code:

const int redPin = 3;
const int greenPin = 6;
const int bluePin = 5;
const int buttonPin = 10;
const int ledPin = 7;

int ledState = LOW;         
int buttonState;             
int lastButtonState =HIGH;
long lastDebounceTime = 0;
long debounceDelay = 100;

void setup() {
  // Start off with the LED off.
  pinMode(buttonPin,INPUT);
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin, ledState);
}

void loop() {
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  } 
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
        ledState = !ledState;
        digitalWrite(ledPin, ledState);

        setColourRgb(0,0,0);
        unsigned int rgbColour[3];


        // Start off with red.
        rgbColour[0] = 255;
        rgbColour[1] = 0;
        rgbColour[2] = 0;  

        // Choose the colours to increment and decrement.
        for (int decColour = 0; decColour < 3; decColour += 1) {
          int incColour = decColour == 2 ? 0 : decColour + 1;

          // cross-fade the two colours.
          for(int i = 0; i < 255; i += 1) {
            rgbColour[decColour] -= 1;
            rgbColour[incColour] += 1;

            setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
            delay(5);

          }
        }
      }
    }
  }
  //digitalWrite(ledPin, ledState);
  lastButtonState = reading;
}

void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
  int reading = digitalRead(buttonPin);
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}
void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
  int reading = digitalRead(buttonPin);

Why do this? The variable "reading" only has validity in the setColourRgb function, and it is not being used. This variable has nothing to do with the variable called "reading" that is declared in the loop function. This is known as a variable's scope. Any variable declared inside a function is only valid inside THAT function. Once the function is over that variable is forgotten. What are you trying to do here?

You still have not got the braces paired correctly, sure they match so it compiles but that is all. I think it would help if you cut up the loop function into a number of separate function so you could see the structure better.

You should have a boolean variable that flags when the fading is finished, so that you know when to reset the numbers to start the fade again.