RGB Led, School-project, need help!

Hi everyone!

Could really use some help with a small project me & my friend are doing, which shall be finished by tomorrow :disappointed_relieved:

In short we want to make a rgb-led flash in random colors, approx 9 different, and make the led stop randomizing when a button is pressed.

We also need a on/off switch, preferably a simple button in lack of hardware...

So the whole process should be;

  1. turn on (button 1)
  2. press (button 2) to make the led light up with random colors
  3. press (button 2) again for led to fix the color
  4. press (button 2) to make the led start randomizing again...
  5. turn off

You get the point. AND by the way, we don't want any fading between the colors.

We have tried ¨hacking¨ some code, but we can't get the buttons to work as we intended.

Check the Fritz-file to see how I wired it up. Feel free to make changes if it sucks.

Thanks in advance!

rgb-led_Assignment.fzz (8.92 KB)

We used this code for making the led light up in different colours: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1285904797

int redLed = 11;
int greenLed = 10;
int blueLed = 9;

int btn1 = 4;
int btn2 = 5;

boolean random = true;
boolean turnOn = true;

long randNumb;
long randTime;

void setup()
{
 pinMode(redLed, OUTPUT);
 pinMode(greenLed, OUTPUT);
 pinMode(blueLed, OUTPUT);
}

void red()
{
 analogWrite(redLed, 255);
 analogWrite(greenLed, 0);
 analogWrite(blueLed, 0);
}

void green()
{
 analogWrite(redLed, 0);
 analogWrite(greenLed, 255);
 analogWrite(blueLed, 0);
}

void blue()
{
 analogWrite(redLed, 0);
 analogWrite(greenLed, 0);
 analogWrite(blueLed, 255);
}

void yellow()
{
 analogWrite(redLed, 255);
 analogWrite(greenLed, 255);
 analogWrite(blueLed, 0);
}

void orange()
{
 analogWrite(redLed, 255);
 analogWrite(greenLed, 35);
 analogWrite(blueLed, 255);
}

void pink()
{
 analogWrite(redLed, 255);
 analogWrite(greenLed, 0);
 analogWrite(blueLed, 162);
}

void purple()
{
 analogWrite(redLed, 88);
 analogWrite(greenLed, 0);
 analogWrite(blueLed, 112);
}

void bluegreen()
{
 analogWrite(redLed, 0);
 analogWrite(greenLed, 144);
 analogWrite(blueLed, 255);
}

void white()
{
 analogWrite(redLed, 255);
 analogWrite(greenLed, 255);
 analogWrite(blueLed, 255);
}

void loop()
{
if (random && turnOn) {
 randNumb = random(1, 10);	// Generate a random number between 1 and 10
 randTime = random(250, 1001);  // Generate a random number between 250 and 1000

 if(randNumb == 1){
  red();
 }
 if(randNumb == 2){
  green();
 }
 if(randNumb == 3){
  blue();
 }
 if(randNumb == 4){
  yellow();
 }
 if(randNumb == 5){
  orange();
 }
 if(randNumb == 6){
  pink();
 }
 if(randNumb == 7){
  purple();
 }
 if(randNumb == 8){
  bluegreen();
 }
 if(randNumb == 9){
  white();
 }

 delay(randTime);
}
else if (not turnOn) {
analogWrite(redLed, 0);
analogWrite(greenLed, 0);
analogWrite(blueLed, 0);
}
else if (not random) {
analogWrite(redLed, 50);
analogWrite(greenLed, 50);
analogWrite(blueLed, 50);
}

if (digitalRead(btn1) == HIGH) {
random = not random;
}

if (digitalRead(btn2) == HIGH) {
turnOn = not turnOn;
}

}

something like this? i did not test it yet, but i think it should work..

Thanks!

Is my circuit ok?

nice solution steen,

could be really refactored !!

void green()
{
 analogWrite(redLed, 0);
 analogWrite(greenLed, 255);
 analogWrite(blueLed, 0);
}

==>

void green()  // and all others 
{
  color(0,255,0);
}

void color(int R, int G, int B)
{
 analogWrite(redLed, R);
 analogWrite(greenLed, G);
 analogWrite(blueLed, B);
}

--Cripes, I can't type a post without others sliding in ahead and changing the field!--

Are you debouncing your buttons? That last example uses no debounce.

Also, random colors... you need only generate sets of 3 0-255 randoms and pass them to 1 routine that uses 3 PWM pins to power the led. The real hard part is getting good 'randoms'. If you can feed it a seed now and then it would help otherwise perhaps reading an unterminated analog pin for the least significant digits might do for randoms or seeds.

If/when you post your code, use the # key (above the smilies) to make code tags for it. Quote tags won't do and that tool in the IDE to post your code is even worse. Just select all, copy, set up the code tags and paste in between.

I dunno what it takes to show the Fritzing in your post but other people do it. I don't have anything to view the file with otherwise so I guess you must have wired everything up right.

Done by tomorrow? It could be.

You can download Fritzing for free @ ; Download Fritzing

A comment to the post by Steen.

It says ¨error: in argument to unary¨, for boolean random = true;

I don't know anything about boolean :/...

@inicko: take a screenshot of your Fritzing file and post it ... it will make the commenting much easier.

/d

screenshot

i see only one button there ö weren't there 2 buttons? one for stopping and one for pausing?

First thing:

remove the button from pin 13 and place it in pin 12 instead. Pin 13 contains a resistor and an LED that will mess up with the values of your input.

Then:

add your second button to pin 8

Finally, use the code proposed by @Steen with some small modifications as shown here:

int redLed = 11;
int greenLed = 10;
int blueLed = 9;

int btn1 = 12;
int btn2 = 8;

boolean rnd = true;
boolean turnOn = true;

long randNumb;
long randTime;

void setup()
{
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
  
  pinMode(btn1, INPUT);
  digitalWrite(btn1, HIGH);
  pinMode(btn2, INPUT);
  digitalWrite(btn2, HIGH);
}

void red()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 0);
}

void green()
{
  analogWrite(redLed, 0);
  analogWrite(greenLed, 255);
  analogWrite(blueLed, 0);
}

void blue()
{
  analogWrite(redLed, 0);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 255);
}

void yellow()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 255);
  analogWrite(blueLed, 0);
}

void orange()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 35);
  analogWrite(blueLed, 255);
}

void pink()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 162);
}

void purple()
{
  analogWrite(redLed, 88);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 112);
}

void bluegreen()
{
  analogWrite(redLed, 0);
  analogWrite(greenLed, 144);
  analogWrite(blueLed, 255);
}

void white()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 255);
  analogWrite(blueLed, 255);
}

void loop()
{
  if (rnd && turnOn) {
    randNumb = random(1, 10);	// Generate a random number between 1 and 10
    randTime = random(250, 1001);  // Generate a random number between 250 and 1000

    if(randNumb == 1){
      red();
    }
    if(randNumb == 2){
      green();
    }
    if(randNumb == 3){
      blue();
    }
    if(randNumb == 4){
      yellow();
    }
    if(randNumb == 5){
      orange();
    }
    if(randNumb == 6){
      pink();
    }
    if(randNumb == 7){
      purple();
    }
    if(randNumb == 8){
      bluegreen();
    }
    if(randNumb == 9){
      white();
    }

    delay(randTime);
  }
  else if (not turnOn) {
    analogWrite(redLed, 0);
    analogWrite(greenLed, 0);
    analogWrite(blueLed, 0);
  }
  else if (not rnd) {
    analogWrite(redLed, 50);
    analogWrite(greenLed, 50);
    analogWrite(blueLed, 50);
  }

  if (digitalRead(btn1) == HIGH) {
    rnd = not rnd;
  }

  if (digitalRead(btn2) == HIGH) {
    turnOn = not turnOn;
  }

}

Thanks David!

and yes there's supposed to be two buttons, but I forgot to add the 2nd one XD

If it's not running off a PC then button 1 should also be known as the power switch on the power strip.

How should I connect the buttons?

from pin 8 or 12 to the button, but then what?

The other pin has to go to ground. You don't need any resistors, because the code is activating an internal resistor in the processor. Actually this reminds me that you need to compare the buttons to LOW and not HIGH to check whether they are pressed or not, since by default they will be HIGH. Here the modified software:

int redLed = 11;
int greenLed = 10;
int blueLed = 9;

int btn1 = 12;
int btn2 = 8;

boolean rnd = true;
boolean turnOn = true;

long randNumb;
long randTime;

void setup()
{
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
  
  pinMode(btn1, INPUT);
  digitalWrite(btn1, HIGH);
  pinMode(btn2, INPUT);
  digitalWrite(btn2, HIGH);
}

void red()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 0);
}

void green()
{
  analogWrite(redLed, 0);
  analogWrite(greenLed, 255);
  analogWrite(blueLed, 0);
}

void blue()
{
  analogWrite(redLed, 0);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 255);
}

void yellow()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 255);
  analogWrite(blueLed, 0);
}

void orange()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 35);
  analogWrite(blueLed, 255);
}

void pink()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 162);
}

void purple()
{
  analogWrite(redLed, 88);
  analogWrite(greenLed, 0);
  analogWrite(blueLed, 112);
}

void bluegreen()
{
  analogWrite(redLed, 0);
  analogWrite(greenLed, 144);
  analogWrite(blueLed, 255);
}

void white()
{
  analogWrite(redLed, 255);
  analogWrite(greenLed, 255);
  analogWrite(blueLed, 255);
}

void loop()
{
  if (rnd && turnOn) {
    randNumb = random(1, 10);	// Generate a random number between 1 and 10
    randTime = random(250, 1001);  // Generate a random number between 250 and 1000

    if(randNumb == 1){
      red();
    }
    if(randNumb == 2){
      green();
    }
    if(randNumb == 3){
      blue();
    }
    if(randNumb == 4){
      yellow();
    }
    if(randNumb == 5){
      orange();
    }
    if(randNumb == 6){
      pink();
    }
    if(randNumb == 7){
      purple();
    }
    if(randNumb == 8){
      bluegreen();
    }
    if(randNumb == 9){
      white();
    }

    delay(randTime);
  }
  else if (not turnOn) {
    analogWrite(redLed, 0);
    analogWrite(greenLed, 0);
    analogWrite(blueLed, 0);
  }
  else if (not rnd) {
    analogWrite(redLed, 50);
    analogWrite(greenLed, 50);
    analogWrite(blueLed, 50);
  }

  if (digitalRead(btn1) == LOW) {
    rnd = not rnd;
  }

  if (digitalRead(btn2) == LOW) {
    turnOn = not turnOn;
  }

}

more precisely should i wire?

In the code, right up top, which pin to which button.

button 1: pin 12 --- button --- ground
button 2: pin 8 --- button --- ground

Your led is on pins 9, 10, 11.

I could suggest some debounce in the code? Use it if the circuit acts up, some buttons are better than others, some stink. I tested this code by plugging 1 jumper in a digital pin hole and 1 jumper in ground. Then I touched the other ends of the jumpers together, and I wiped them across each other, etc. And then I did the same but using digitalRead() without the debounce and really what I learned is either touching jumper pins is pretty clean or I can see the output change fast enough to catch it all, because at times it looked like it. So don't bother unless your buttons seem 'unsteady'.

getButton() would replace your call(s) to digitalRead() -- only in case of button trouble

byte getButton( byte pin )
{
  byte A, B, C = 0;
  A = digitalRead( pin );
  while ( C < 4 ) // need 3 matching reads in a row, 5 ms apart, to determine button state
  {
    delay( 5 );    // this can be adjusted but more than 10 would be for a really baaaad button
    B = digitalRead( pin );
    if ( B == A )   // match, increment C
    {
      C++;
    }
    else {           // not match, start over with the last read state
      C = 0;
      A = B;
    }
  }
}

looks good, but where do you returns your 'byte' ? since you declare it as returning one..

and why is a button high in standard state? i always thought it was low..?

Now that's really weird because, it works and you're right, it shouldn't!

I am running 0022. Here's the q&d test code that I just recompiled and it runs and does what I expect!

I ground the jumper in 7 to the jumper in GND and the monitor prints 0. I break the connect and it prints 1. Just before the closing bracket there it should say: return A;
But .. it .. WORKS!

void setup( void )
{
  Serial.begin(9600);
  pinMode( 7, INPUT );
  digitalWrite( 7, HIGH );
  pinMode( 3, INPUT );
  digitalWrite( 3, HIGH );
}

byte wasPS3 = 1;
byte pinState3 = 1;

byte wasPS7 = 1;
byte pinState7 = 1;

byte getButton( byte pin )
{
  byte A, B, C = 0;
  A = digitalRead( pin );
  while ( C < 4 ) // need 3 reads in a row, 5 ms apart, that match
  {
    delay( 5 );
    B = digitalRead( pin );
    if ( B == A )
    {
      C++;
    }
    else {
      C = 0;
      A = B;
    }
  }
}

void loop( void )
{
  pinState3 = digitalRead( 3 );
  if ( pinState3 != wasPS3 )
  {
    wasPS3 = pinState3;
    Serial.println( pinState3 + 100, DEC );
  }

  pinState7 = getButton( 7 );
  if ( pinState7 != wasPS7 )
  {
    wasPS7 = pinState7;
    Serial.println( pinState7, DEC );
  }
}

Must be something the compiler did. Maybe the first time ever a compiler fix my F-U.

I made the change and on test it still works:

byte getButton( byte pin )
{
  byte A, B, C = 0;
  A = digitalRead( pin );
  while ( C < 4 ) // need 3 reads in a row, 5 ms apart, that match
  {
    delay( 5 );
    B = digitalRead( pin );
    if ( B == A )
    {
      C++;
    }
    else {
      C = 0;
      A = B;
    }
  }
  return  A;
}

And as far as should the button read HIGH or LOW when not pressed, the answer is that it depends on how it's wired up and what you do with the pins.

In this case the power is fed through about a 20k internal resistor to the pin the 'button' is connected to. There's almost not enough current there to light up a led (a red one, it was pathetic little glow and didn't bring pin 7 low... try it!) much less burn out a pin. It's safe and it doesn't require me extra parts beyond 3 jumpers and the UNO to run my test.

And my test says it takes dirty switches to need debouncing! Dirtier than touching jumper ends at least.

And LOL, 5V through 220R to a red led makes one very bright red led. Through 20k and it's Mick Jagger, one of the Glimmer Twins! Because that's -all- I got was a near dead cig-butt glimmer!