Go Down

### Topic: Controlling RGB LED with two buttons. (Read 3865 times)previous topic - next topic

#### cgarberg

##### Mar 29, 2012, 01:03 am
I am working on a project where i can control the color on an RGB LED using only two buttons. The colors need to cycle through 7 colors (red, green, blue, purple, aqua, yellow, and white), with the buttons serving the function of navigating backwards and forwards. Can anyone give me a hand with the programming?

#### PaulS

#1
##### Mar 29, 2012, 02:05 am
What parts of the programming are you having problems with? Reading the state of a switch is trivial. Incrementing or decrementing a variable based on the state of the pins is trivial. Using a switch/case statement to handle what to do depending on the variable value is easy.

#### cgarberg

#2
##### Mar 29, 2012, 07:03 am
I understand that it is all very simple programming, and in theory i should be able to do it. However i have close to no experience programming, this is for a school related project. I feel like it is simply a matter of using the correct logistics, and unfortunately, I cannot.

#### Grumpy_Mike

#3
##### Mar 29, 2012, 09:48 am
You need to tell us what pins you are using for the buttons, how they are wired up. The same goes for the LED, how is it wired up are you using the same value of resistor for each colour, are you expecting just primary and secondary colours or do you want a continuous mix!

#### tigerbomb8

#4
##### Mar 29, 2012, 11:17 amLast Edit: Mar 29, 2012, 11:26 am by tigerbomb8 Reason: 1
this video will help with the buttons and how to debounce them

#### cgarberg

#5
##### Mar 29, 2012, 09:04 pm
The buttons are wired to pins 2 and 3, with a 10K ohm resistor between the 5v source and the pin and button. The RGB LED is wired to pins 9 (blue), 10 (green) and 11 (red), with a 330 ohm resistor between each pin and the LED. The colors should be as following, and need to cycle in this order. White, red, blue, green, aqua(green/blue), yellow(red/green) and purple(red/blue). These need to act as if they're fixed to a color wheel and the buttons are used to rotate the wheel backwards or forwards, one step/color at a time.

#### PaulS

#6
##### Mar 30, 2012, 01:29 am
Quote
The RGB LED is wired to pins 9 (blue), 10 (green) and 11 (red), with a 330 ohm resistor between each pin and the LED. The colors should be as following, and need to cycle in this order. White, red, blue, green, aqua(green/blue), yellow(red/green) and purple(red/blue).

Well, there is no analogWrite() method that takes 3 pin numbers and a color name, so you have some work to do.

You need to connect your LED. with resistors, to the three pins, and create a sketch that contains nested for loops that cycle from zero to 255. Write the three values to the serial port. When you see a color you like, make note of the numbers.

Then, write a sketch that detects when a switch has been pressed. When the switch changes state, to pressed, increment a value. Do the same for the other switch, but make this one decrement a value.

Then, create a switch statement, in a for loop. Each case should call analogWrite() 3 times, once for each pin. Each case should set the pins to one of the colors you liked.

Finally, combine parts of the sketches to create a final sketch. That sketch detects switch presses and increments or decrements a value. It contains the switch statement that has cases that set the colors. The switch variable is the value that the switches cause to be incremented/decremented.

Since this is homework, presumably you are supposed to learn something in class that you apply in the homework. So, you need to try something. If you have problems, we'll help. We don't do homework for you, though.

Encouragement, hints, suggestions, links, some answers, if you ask the right questions, etc. are available, but not a completed program. You wouldn't learn anything from that, and it might not even work with your hardware.

#### John_S

#7
##### Mar 30, 2012, 03:00 am
I think the OP wants a simpler way than analog write. Aqua is Blue+Green, Yellow = Red+Green, and Purple=Red+Blue.

Something like this might suffice (not compiled or tested):
Code: [Select]
`const int BluePin = 9;const int GreenPin = 10;const int RedPin = 11;const int IncrementButton = 2;int colormode;void setup(){  pinMode (BluePin, OUTPUT);  pinMode (GreenPin, OUTPUT);  pinMode (RedPin, OUTPUT);  pinMode (Incrementbutton, INPUT);}void loop(){  switch (colormode){    case 1: //white    digitalWrite(BluePin, HIGH);    digitalWrite(GreenPin, HIGH);     digitalWrite(RedPin, HIGH);    break;        case 2: //red    digitalWrite(BluePin, LOW);    digitalWrite(GreenPin, LOW);     digitalWrite(RedPin, HIGH);    break;    ......    case 5: //aqua    digitalWrite(BluePin, HIGH);    digitalWrite(GreenPin, LOW);     digitalWrite(RedPin, HIGH);    break;    case 6: //yellow    digitalWrite(BluePin, HIGH);    digitalWrite(GreenPin, HIGH);     digitalWrite(RedPin, LOW);    break;......ect...}`

#### cgarberg

#8
##### Mar 30, 2012, 05:25 am
Coding the colors is simple and i have figured it out. At this point, i am unsure of what type of function to use to switch between the colors. Something along these lines maybe...?

Code: [Select]
`const int redledPin = 11;const int greenledPin = 10;const int blueledPin = 9;const int buttonPin1 = 2;const int buttonPin2 = 3;void setup (){  pinMode (redledPin, OUTPUT);  pinMode (greenledPin, OUTPUT);  pinMode (blueledPin, OUTPUT);  pinMode (buttonPin1, INPUT);  pinMode (buttonPin2, INPUT);}    analogWrite(redledPin, 250);analogWrite(blueledPin, 250);analogWrite(greenledPin, 0);if (digitalRead(buttonPin1)==LOW) { (switch to purple) }if (digitalRead(buttonPin2)==LOW) { (switch to red) }etc. `

I feel like the solution is really simple and im just not familiar enough with the arduino programming to utilize the correct functions.

#### cgarberg

#9
##### Mar 30, 2012, 06:12 am
Ok, i've made a bit of progress. All i lack currently is how to choose which case to display. If i write "switch (color)", would i then increment my colors by writing something similar to this?
Code: [Select]
` if (digitalRead(buttonPin1)== LOW);  {for (color>0; color<7; color++)    {}  if (color=7)    {color-6;}  }    if (digitalRead(buttonPin2)== LOW);  {for (color>1; color<8; color-- )    {}  if (color=1)  {color+6;}  }`

#### John_S

#10
##### Mar 30, 2012, 06:47 pm
close, but not quite... try something like this:
Code: [Select]
`if (digitalRead(buttonPin1)== LOW);{  color++; //increment color  if (color >7) color = 0;}  if (digitalRead(buttonPin2)== LOW);{  color--;  //decrement color  if(color<0) color = 7;}`

#### cgarberg

#11
##### Mar 30, 2012, 07:17 pm
Quote
Then, create a switch statement, in a for loop. Each case should call analogWrite() 3 times, once for each pin. Each case should set the pins to one of the colors you liked.

What do i write in the for loop? As in:

for(what?){
switch(color){
etc...}}

#### PaulS

#12
##### Mar 31, 2012, 01:22 am
Code: [Select]
`if (digitalRead(buttonPin1)== LOW);`
Yeah, that will work great. Of course, it'd be even better without the ; on the end...

#### cgarberg

#13
##### Mar 31, 2012, 08:07 am
Quick update: I now have a working code. Thanks for all the help everyone. The only problem is that if one of the buttons is held down, the colors will cycle automatically. I have added a delay that somewhat counteracts this, however this project is being designed for a handicapped woman, and i would like to remove any and all possible user error from the equation. Basically, is there a way to limit the program so that no matter how long a button is held down for, it will only step once?
Here is my current code:
Code: [Select]
`const int redledPin = 11;const int greenledPin = 10;const int blueledPin = 9;const int buttonPin1 = 2;const int buttonPin2 = 3;int color=1;void setup (){  pinMode (redledPin, OUTPUT);  pinMode (greenledPin, OUTPUT);  pinMode (blueledPin, OUTPUT);  pinMode (buttonPin1, INPUT);  pinMode (buttonPin2, INPUT);}void loop (){ if (digitalRead(buttonPin1)== LOW){  color++; //increment color  if (color >7) color = 1;  delay(750);}  if (digitalRead(buttonPin2)== LOW){  color--;  //decrement color  if(color<1) color = 7;  delay(750);}     switch (color){    case 1: //white    analogWrite(redledPin, 250);    analogWrite(blueledPin, 250);    analogWrite(greenledPin, 250);    break;        case 2: //red    analogWrite(redledPin, 250);    analogWrite(blueledPin, 0);    analogWrite(greenledPin, 0);    break;        case 3: //blue    analogWrite(redledPin, 0);    analogWrite(blueledPin, 250);    analogWrite(greenledPin, 0);    break;        case 4: //green    analogWrite(redledPin, 0);    analogWrite(blueledPin, 0);    analogWrite(greenledPin, 250);    break;        case 5: //aqua    analogWrite(redledPin, 0);    analogWrite(blueledPin, 250);    analogWrite(greenledPin, 250);    break;        case 6: //yellow    analogWrite(redledPin, 250);    analogWrite(blueledPin, 0);    analogWrite(greenledPin, 250);    break;        case 7: //purple    analogWrite(redledPin, 250);    analogWrite(blueledPin, 250);    analogWrite(greenledPin, 0);    break;   }}        `

#### PaulS

#14
##### Mar 31, 2012, 02:57 pm
Quote
The only problem is that if one of the buttons is held down, the colors will cycle automatically.

What you need to do is to detect the transition, from released to pressed or from pressed to released, and only increment/decrement the value at the correct transition.

This requires keeping track of the previous state of the switches.
Code: [Select]
`int prevUp = HIGH;int prevDn = HIGH;void loop(){   int currUp = digitalRead(buttonPin1);   if(currUp != prevUp) // A transition occurred   {      if(currUp == LOW)         color++;   }   prevUp = currUp;   // handle other switch   // Set LED pins}`

Might I suggest that more meaningful names are useful. buttonPin1 doesn't mean a lot. upPin does, to me, at least. Ditto for buttonPin2 ==> dnPin.

Also, pressing the up and down buttons does not directly change the color. It changes the mode that will be used to set the pins to produce the color. So, a name like colorMode says that the variable controls the mode, not the color.

Otherwise, the code looks good. I knew you could get there.