Go Down

Topic: Controlling RGB LED with two buttons. (Read 1 time) previous topic - next topic

cgarberg

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

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

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

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 am Last Edit: Mar 29, 2012, 11:26 am by tigerbomb8 Reason: 1
this video will help with the buttons and how to debounce them

http://www.youtube.com/watch?v=_LCCGFSMOr4

cgarberg

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

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

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...
}
http://jsrintervalometers.blogspot.ca

cgarberg

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

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

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;
}
http://jsrintervalometers.blogspot.ca

cgarberg

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

Code: [Select]
if (digitalRead(buttonPin1)== LOW);
Yeah, that will work great. Of course, it'd be even better without the ; on the end...

cgarberg

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

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.

Go Up