Push Buttons not working as expected to toggle RGB LED on and off.

I am new to Arduino programming and tried a few of the tutorial examples on the net with success. So I decided to be adventurous and do the following:

4 push buttons that would each toggle a single RGB LED to be red, green, blue or purple. A second toggle of any one button is supposed to switch off the LED.

Here is my code (not used C++ so my code is probably not as concise as it could be…I’ll work on it XD):

int redPin = 11;
int greenPin = 10;
int bluePin = 9;
int redButtonPin = 8;
int greenButtonPin = 7;
int blueButtonPin = 6;
int purpleButtonPin = 5;
bool redON = false;
bool greenON = false;
bool blueON = false;
bool purpleON = false;
 
void setup()
{
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(redButtonPin, INPUT);
  pinMode(greenButtonPin, INPUT);
  pinMode(blueButtonPin, INPUT);
  pinMode(purpleButtonPin, INPUT);
  Serial.begin(9600);
}
 
void loop() {
//  int buttonPressed;
  if (digitalRead(greenButtonPin) == HIGH) {
    if (greenON == true) {
      greenON = false;
      setColor(0,0,0);
    } else {
      greenON = true;
      Serial.println("green on");
      setColor(0,255,0);
    }
    redON = false;
    blueON = false;
    purpleON = false;
  }
  if (digitalRead(blueButtonPin) == HIGH) {
    if (blueON == true) {
      blueON = false;
      setColor(0,0,0);
    } else {
      blueON = true;
      Serial.println("blue on");
      setColor(0,0,255);
    }
    greenON = false;
    redON = false;
    purpleON = false;
  }
  if (digitalRead(purpleButtonPin) == HIGH) {
    if (purpleON == true) {
      purpleON = false;
      setColor(0,0,0);
    } else {
      purpleON = true;
      Serial.println("purple on");
      setColor(255,0,255);
    }
    greenON = false;
    blueON = false;
    redON = false;
  }
  if (digitalRead(redButtonPin) == HIGH) {
    if (redON == true) {
      redON = false;
      setColor(0,0,0);
    } else {
      redON = true;
      Serial.println("red on");
      setColor(255,0,0);
    }
    greenON = false;
    blueON = false;
    purpleON = false;
  }
//  delay(200);
}
 
void setColor(int red, int green, int blue) {
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);  
}

I have attached an image of my bread board layout. If needs be, I can attempt to draw a presentable circuit diagram (I have been told that mine are no good…). To clarify the images, here is a description of the wiring:

  • An Arduino UNO (not pictured) connected by usb to my laptop.
  • RGB LED: 3 input pins wired to 270 Ohm resistors, red going to digital pin 11 on the Arduino, green to pin 10, blue to pin 9; ground wired to the GND on the Arduino.
  • Push Buttons: 1K Ohm resistor wired to each push buttons negative terminal and then to the GND on the arduino; positive terminal wired to the 5V pin on the Arduino; output leads for each button wired to the negative button terminal red to digital pin 8, green to pin 7, blue to pin 6, purple to pin 5.

I am encountering two problems:

  1. toggle on works fine, but I cannot toggle the LED off. I assume that I have made an error with assigning the global variable or there is something wrong in the if statements controlling the off toggle. For the life of me I cannot see it.
  2. This problem is much more serious. All the buttons work except for the red button (top most button on the image) - zip, nada, nothing. I tried the following to debug this problem, but I have not been successful:

a. I replaced the button, lead wire, resistor and yellow connector separately to check whether one of the components were perhaps damaged. No luck.
b. I switch the leads for the green and red button on the breadboard itself (i.e. red to pin 7 and green to pin 8). Now the LED lights up red when you press the original green button, but the original red button still does nothing (it should light up green).
c. I deleted the if statement in my code referring to red button, copied a segment of working code and changed the variables for the red (I thought that perhaps the code for this button was not correct). This made no difference.
d. I cut the red button code and moved it after the purple button’s code. I thought that there may be some variable that I am initialising incorrectly during the first if statement that was causing the error, so I did this to narrow down the problem. No change.
e. No serial output is produced for the button in question.
f. I moved the button, resistor and connecting wired one row up, to see if the bread board might be damaged in that region. No luck.

I have been staring at this code for hours (and the wiring) and I cannot find anything obviously wrong with it.

I hope I have provided sufficient information. If anyone can give me some guidance as to where I am going wrong, I would appreciate it.

Hi CvZyl

Do the switches you are using have four pins arranged in a square? If so, try rotating the “red” switch through 90 degrees.

Also, can you draw a diagram of how you have the switches connected to the resistor, power rails and Arduino.

Regards

Ray

Yes, it is a standard square push button, but is oriented and wired just like the other buttons. I am not at home at the moment so in a few hours when I am back I will draw a diagram and upload it. Thanks!

Casper

On the other problem ...

toggle on works fine, but I cannot toggle the LED off.

if (digitalRead(greenButtonPin) == HIGH) {

Your program is testing to see if the switch is closed, rather than "it was open and now is closed". So for as long as you have the switch pressed, the LED will change very fast between on and off.

There is an Arduino example program called "StateChangeDetection" which shows how to make things happen only at the time the switch closes.

Thank you, Hackscribble. I had a look at the example you mentioned and incorporated it into my sketch. The toggling on and off works now, I just want to refine it slightly so that the 4 buttons work seamlessly together at the start of the sketch. Here is the new code:

int redPin = 11;
int greenPin = 10;
int bluePin = 9;
int redButtonPin = 8;
int greenButtonPin = 7;
int blueButtonPin = 6;
int purpleButtonPin = 5;
int redState = 0;
int redCounter = 0;
int redLastState = 0;
int greenState = 0;
int greenCounter = 0;
int greenLastState = 0;
int blueState = 0;
int blueCounter = 0;
int blueLastState = 0;
int purpleState = 0;
int purpleCounter = 0;
int purpleLastState = 0;
 
void setup()
{
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(redButtonPin, INPUT);
  pinMode(greenButtonPin, INPUT);
  pinMode(blueButtonPin, INPUT);
  pinMode(purpleButtonPin, INPUT);
  Serial.begin(9600);
}
 
void loop() {
  greenState = digitalRead(greenButtonPin);
  if (greenState != greenLastState) {
    if (greenState == HIGH) {
      Serial.println("green on");
      Serial.print("number of pushes: ");
      Serial.println(greenCounter);
      greenCounter++;
    } else {
      Serial.println("green off");
      Serial.print("number of pushes: ");
      Serial.println(greenCounter);
    }
    greenLastState = greenState;
    if (greenCounter % 2 == 0) {
      setColor(0,255,0);
    } else {
      setColor(0,0,0);
    }
  }
  blueState = digitalRead(blueButtonPin);
  if (blueState != blueLastState) {
    if (blueState == HIGH) {
      blueCounter++;
      Serial.println("blue on");
      Serial.print("number of pushes: ");
      Serial.println(blueCounter);
    } else {
      Serial.println("blue off");
      Serial.print("number of pushes: ");
      Serial.println(blueCounter);
    }
    blueLastState = blueState;
    if (blueCounter % 2 == 0) {
      setColor(0,0,255);
    } else {
      setColor(0,0,0);
    }
  }
  purpleState = digitalRead(purpleButtonPin);
  if (purpleState != purpleLastState) {
    if (purpleState == HIGH) {
      purpleCounter++;
      Serial.println("purple on");
      Serial.print("number of pushes: ");
      Serial.println(purpleCounter);
    } else {
      Serial.println("purple off");
      Serial.print("number of pushes: ");
      Serial.println(purpleCounter);
    }
    purpleLastState = purpleState;
    if (purpleCounter % 2 == 0) {
      setColor(255,0,255);
    } else {
      setColor(0,0,0);
    }
  }
  redState = digitalRead(redButtonPin);
  if (redState != redLastState) {
    if (redState == HIGH) {
      redCounter++;
      Serial.println("red on");
      Serial.print("number of pushes: ");
      Serial.println(redCounter);
    } else {
      Serial.println("red off");
      Serial.print("number of pushes: ");
      Serial.println(redCounter);
    }
    redLastState = redState;
    if (redCounter % 2 == 0) {
      setColor(255,0,255);
    } else {
      setColor(0,0,0);
    }
  }
}
 
void setColor(int red, int green, int blue) {
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);  
}

FInd attached an image of the diagram for my circuit - the red is still out. I have ruled out any programming issues. But I still cannot figure out what I might have connected incorrectly as all the buttons are connected exactly the same.

    if (purpleCounter % 2 == 0) {
      setColor(255,0,255);
    if (redCounter % 2 == 0) {
      setColor(255,0,255);

Both of these can’t be true because they use the same output values for two different colours.

the red is still out. I have ruled out any programming issues. But I still cannot figure out what I might have connected incorrectly as all the buttons are connected exactly the same.

Try a short program that just shows the status of the red button pin ...

int redButtonPin = 8;
void setup()
{
  pinMode(redButtonPin, INPUT);
  Serial.begin(9600);
}
void loop()
{
   Serial.println(digitalRead(redButtonPin));
}

If the switch still appears not to be working, try changing to a different Arduino pin.

I think you said you've already tried new jumper from Arduino to switch, new switch, etc?

I’ve taken another look at the photo of your breadboard.

See the attached close-up.

The red line by the +ve bus has a gap in it. The black line by the -ve bus is continuous.

Maybe the +ve bus is in two parts, and the top part (connected to the red button) is actually not connected to +5V. Might be worth checking by adding a jumper across that gap.

:blush: BANG HEAD AGAINST WALL and OTHER SOLID THINGS...

Brilliant and so simple - You need to send me your postal address, because you deserve a cigar for spotting that one! Now it works perfectly. I just assumed that the 5V bus would run the whole length of the board without interruption like the GND one. I'll have to look out for that in the future.

The setColor(255,0,255) happened when I copied the working purple code. I edited it for the red button, but forgot to change the colour value (IDEs should actually not allowing copy/pasting in the interface as it leads to stupid mistakes like this and I love to copy/paste my way through things).

Thanks a million! On to the next challenge: LCD screen.

Glad it’s working :slight_smile:

A small improvement to the code and hardware would be to use the Arduino internal pullup resistors for your switches …

Remove your external pullup resistors. Connect the short yellow jumpers to GND instead of +5V. In the code, change the pinMode statements to …

pinMode(redButtonPin, INPUT_PULLUP);

And change your if statements to test for LOW instead of HIGH to indicate that switch is pressed …

if (greenState == LOW) {

Saves a few components and (if you ever end up with switches mounted remotely from the Arduino) reduces risk of electrical noise pickup on the +5V bus.