Swapping from using 3 LEDs to a single RGB LED

I have put together a system that uses 2 buttons per LED to adjust the brightness up and down for each LED. The LEDs are connected to the arduino on pins 9, 10, and 11 to the cathode and then there is a 220 ohm resistor from the anode to ground. Now i have purchased a single RGB LED and now the wiring has to change. Now the Cathode has to be tied into +5V and then the resistors and the pins are wired to there corresponding anodes. Pin 9 goes to the red anode, pin 10 to the green anode and pin 11 to the blue anode. Problem is now it doesn’t step up and down in brightness. When i hit my up button it turns the corresponding color full on and the down buttons do nothing. How can i fix this? If there a hardware issue here or should my sketch change.

/*
  RGB Color Wheel
  
  Indivigually control the brightness of a Red LED, Blue LED and 
  Green LED using 6 pushbuttons attached to pins 2 thru 7. The
  pushbuttons on the even number pins will brighten the corosponding
  LED and the odd numbered ones will dim them. LEDs will be attached
  to pins 9, 10, and 11. 
  
  The Circuit:
  * Red LED from pin 9 to ground threw a 220 Ohm resistor
  * Blue LED from pin 10 to ground threw a 220 Ohm Resistor
  * Green LED from Pin 11 to ground threw a 220 Ohm Resistor
  * pushbutton 1 attached to pin 2 from ground
  * pushbutton 2 attached to pin 3 from ground
  * pushbutton 3 attached to pin 4 from ground
  * pushbutton 4 attached to pin 5 from ground
  * pushbutton 5 attached to pin 6 from ground
  * pushbutton 6 attached to pin 7 from ground
    
  created 13 Jan 2010
  by digimike
  modified 14 jan 2010
  by digimike
  */
  
  
  int redled = 9;    // assign LEDs to pins
  int greenled = 10; 
  int blueled = 11;
  int button2 = 2;    // assign pushbuttons to pins
  int button3 = 3;
  int button4 = 4;
  int button5 = 5;
  int button6 = 6;
  int button7 = 7;
  
  int button2State = 0;    // variable for reading the pushbuttons
  int button3State = 0;
  int button4State = 0;
  int button5State = 0;
  int button6State = 0;
  int button7State = 0;
  int fadered = 0;    // starting brightness values for each led
  int fadegreen = 0;
  int fadeblue = 0;
 
 
 
  void setup () {     
    pinMode(button2, INPUT);    //initialize pushbutton pins as input:
    pinMode(button3, INPUT);
    pinMode(button4, INPUT);
    pinMode(button5, INPUT);
    pinMode(button6, INPUT);
    pinMode(button7, INPUT);
    digitalWrite(button2, HIGH);
    digitalWrite(button3, HIGH);
    digitalWrite(button4, HIGH);
    digitalWrite(button5, HIGH);
    digitalWrite(button6, HIGH);
    digitalWrite(button7, HIGH);     
  }
  
  void loop() {
    button2State = digitalRead(button2);    //check button state
    if(button2State == LOW && fadered <= 250) {
      // if button is pressed increase brightness by 5
      // as long as brightness isn't greater than 250
      fadered +=5;
      analogWrite(redled, fadered);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times 
      if (fadered >= 255) {
        // when led reaches 255 blink the led once
        digitalWrite(redled, LOW);
        delay(1000);
        digitalWrite(redled, HIGH);
      }  
    }
    
    button3State = digitalRead(button3);    //check button state
    if (button3State == LOW && fadered >= 5) {
      // if button is pressed decrease brightness by 5
      // as long as brightness isn't less than 5
      fadered -=5;
      analogWrite(redled, fadered);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times
    }
    
    button4State = digitalRead(button4);    //check button state
    if (button4State == LOW && fadegreen <= 250) {  
      // if button is pressed increase brightness by 5
      // as long as brightness isn't greater than 250
      fadegreen +=5;
      analogWrite(greenled, fadegreen);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times
      if (fadegreen >= 255) {
        // when led reaches 255 blink the led once
        digitalWrite(greenled, LOW);
        delay(1000);
        digitalWrite(greenled, HIGH);
      }  
    }
    
    button5State = digitalRead(button5);    //check button state
    if (button5State == LOW && fadegreen >= 5) {  
      // if button is pressed decrease brightness by 5
      // as long as brightness isn't less than 250
      fadegreen -=5;
      analogWrite(greenled, fadegreen);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times
    }
    
   button6State = digitalRead(button6);    //check button state
    if (button6State == LOW && fadeblue <= 250) {  
      // if button is pressed increase brightness by 5
      // as long as brightness isn't greater than 250
      fadeblue += 5;
      analogWrite(blueled, fadeblue);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times
      if (fadeblue >= 255) {
        // when led reaches 255 blink the led once
        digitalWrite(blueled, LOW);
        delay(1000);
        digitalWrite(blueled, HIGH);
      }  
    }
    
    button7State = digitalRead(button7);    //check button state
    if (button7State == LOW && fadeblue >= 5) {  
      // if button is pressed decrease brightness by 5
      // as long as brightness isn't less than 250
      fadeblue -= 5;
      analogWrite(blueled, fadeblue);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times
    }
  }

Are you really using external pull-downs and internal pull-ups, or are the comments older than the code?

old comments. no pull downs in use. OP will be fixed.

What stops "down" button presses going negative?

Can I suggest you cut out all the blue and green code and concentrate on red? Your program can be factored once you've got red working. Arrays will help here. Calling "button2" something like "RED_UP" or "RED_DOWN" or whatever would make it easier to read.

initially i was focusing on the red.

her is the scaled down and renamed sketch.

/*
  created 14 Jan 2010
  by digimike
  modified 14 jan 2010
  by digimike
  */
  
  
  int redled = 9;    // assign LEDs to pins
  int redup = 2;    // assign pushbuttons to pins
  int reddown = 3;
  
  int r_btn_up = 0;    // variable for reading the pushbuttons
  int r_btn_down = 0;
  int fadered = 0;    // starting brightness values for each led
  
 
  void setup () {     
    pinMode(redup, INPUT);    //initialize pushbutton pins as input:
    pinMode(reddown, INPUT);
    digitalWrite(redup, HIGH);
    digitalWrite(reddown, HIGH);
  }
  
  void loop() {
    r_btn_up = digitalRead(redup);    //check button state
    if(r_btn_up == LOW && fadered <= 250) {
      // if button is pressed increase brightness by 5
      // as long as brightness isn't greater than 250
      fadered +=5;
      analogWrite(redled, fadered);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times 
      if (fadered >= 255) {
        // when led reaches 255 blink the led once
        digitalWrite(redled, LOW);
        delay(1000);
        digitalWrite(redled, HIGH);
      }  
    }
    
    r_btn_down = digitalRead(reddown);    //check button state
    if (r_btn_down == LOW && fadered >= 5) {
      // if button is pressed decrease brightness by 5
      // as long as brightness isn't less than 5
      fadered -=5;
      analogWrite(redled, fadered);  // lights LED at current brightness level
      delay(250);  // allows time so button won't be detected multiple times
    }
    
 }

As for what prevents it from going below zero. The if statement does that.

if (r_btn_down == LOW && fadered >= 5)

if the down button is pressed and the led brightness is >= 5 then it will execute the rest of the statement thus subtracting 5 from the brightness. So now its at 0 and the if statement is unable to exacute again till the brightness is at or above 5.

Now the code works out fine as long as pin 9 goes to the LED’s cathode and the anode is attached to ground. But the RGB LED has only a single cathode and its the anodes that receives power to light the corresponding color. So i need a way to get the analogWrite to output a negative voltage rather then positive.
http://www.seeedstudio.com/depot/images/product/led.jpg

Wait a second.. in a LED you always put the ground to the Cathode and the power on the Anode:

So first, are you 100% sure that you have a common cathode LED? If so, this pin should go to ground.

(Btw you probably know this, don't mean to belittle you in any way) Do the colors of the led light up properly when you just run the "blink" sketch on them?

Then the image i was looking at has it labeled wrong. But either way the common lead on the RGB is positive and the leads leading to the individual colors is negative. As will all LEDs it only lights when power is going the right way. So unless i can figure out a way to have an analogWrite aka pins 9, 10, and 11 over ground rather then positive voltage i can’t use an RGB. Which is odd considering my little sketch here would be allot cooler on an RGB then a single red, green, and blue LED.

What you could try is attach the common anode to your positive lead. Then attach a resistor to each of the individual cathodes, and use a transistor to pull that channel to ground.

RGB LEDs come in common anode or common cathode configuration. If you had the common cathode kind, it would work. Not that I like Sparkfun anymore, but they do have these:

http://www.sparkfun.com/commerce/product_info.php?products_id=105

Right now my source is radioshack. i have 2 within a half mile of my place. Seams all they offer is the common anode. guess i'll order a pack of them from Mouser or Allied. Radioshack use to be such a nice place for picking up parts. Not the cheapest but it was worth it if you needed it right then.

get some pnp transistors, pwm is just timed pulses of 0 to 5 volts that "look" like analog voltages, but its really the average voltage against the time on/off pulse

back to the point when the pwm is in a high state, use that signal to switch the transistor which is connected tween the cathode and ground

you can get a generic 15 pack mix down at radio shack for a few bucks (and get some 1k resistors to connect tween the arduino and the transistor) [edit] Blammers posted the same thing[/edit]

Sparkfun offers quick delivery. If you don't mind spending $32 for a $2 part...

Well the $1.95 is better then radioshacks 2.99. Too bad shipping is always the problem. I'd have to order several things to make it worth my time. Guess i'll hold off on getting the LED till i have a list of things i need.

Blammers had it right. Common anodes are the most common type of RGB LED because this is the most useful configuration. I have done this many times, that is driven a common anode RGB LED through three PWM pins of an arduino. Put the anode to +5 and separate resistors in each cathode then to the arduino output. This is called current sinking and is the way it is done in 99% of all electronic circuits. Current sourcing while it might look to a beginner as "natural" is not the most efficient way to design a chip. For an example of an RGB LED from three PWM pins see my Arduinocaster video. http://www.youtube.com/watch?v=ehy9xgl4YCs

I need to try that but i’m such a noob with electronics. If i had a schematic i can build it. I may not understand how or why it works but i’m getting there. I took electronics classes back in high school but that was about 12 years ago and i’ve forgot most of what little i learned there. It was a self paced class and i did a whole lot of nothing durring most of it. So i’m trying to relearn all i missed and then some. I even picked up the same electronics book i had back them. Still have the workbook from the class too.

Now i have tried connecting the anode to the +5 and running the 220 Ohm resisters off the cathodes to there corresponding PWM pins but when i push my brightness up button the LED just turns on. It doesn’t stup up the brightness like it should. The down button does nothing. It should be dimming the led but it doesn’t. The code works when the PWMs are on the Anode. I’m hoping there is some changes i can make to the code to fix this.

Some people have mentioned the use of some PNP Transistor. This is one of the many things that is over my head right now. It also seams like the way the code works will have to completely change.

In that code you are mixing up digitalWrite() and analogWrite() in the same sketch. You should not do this because I understand that the digitalWrite() removes the PWM assignment from the pin. So it looks like that is the problem you are having. For just one RGB LED on three PWM pins you don't need any extra transistors. Each colour must have it's own resistor in the cathode with the common anode going to +. To balance things up I put different values of resistor in each colour. With 220R for red, 512R for blue and 910R for green.

The drigitalWrite being used is for detecting the button push. I was told it was a way to use pushbuttons without the need of pull down resistor connected to the button. Telling the Arduino to consider the input from those pins to be high. That way when i press the button and the ground is passed threw to those pins it will read low.

From my thread on the software side.

Assuming you're talking about pull-ups, you don't need any external pull-ups, simply use the AVR's built-in ones, enabled by a "digitalWrite" to the appropriate input pin (after you've set the "pinMode"). Connect the switches between the input and ground, and remember this will invert your logic; a closed switch will read LOW.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1263482014

I understand what you talking about with the RGB but its just not working. The PWM pins are outputting a positive voltage by default. If i can get them to go negative then i can use this RGB. Like i said the program works perfectly well when a separate red, green, and blue LEDs are being used. But then there anodes are connected to the PWM and the Cathode is connected to ground.

The drigitalWrite being used is for detecting the button push.

In the original sketch posted, it is also being used to blink the LEDs.

  // when led reaches 255 blink the led once
        digitalWrite(redled, LOW);
        delay(1000);
        digitalWrite(redled, HIGH);

If i can get them to go negative then i can use this RGB

I don't think you understand how PWM works.

If you're driving the PWM with, say, a 25% duty-cycle ("analogWrite (LED_PIN, 64)"), the line is high for 25% of the time, and low for 75%. For a LED connected between pin and ground (and ignoring for now the logarithmic response of the LED) the LED would show 25% brightness. The pin is sourcing current for 25% of the time.

However, the same signal applied to a LED connected between pin and supply would show 75% brightness. The pin is sinking current for 75% of the time. To get 25% brightness from the same LED, you would do "analogWrite (255 - 64);"

Enabling pull up resistors and pins as inputs should only be done in the setup section.

For a look at how PWM works see:- http://www.thebox.myzen.co.uk/Tutorial/PWM.html

The PWM pins are outputting a positive voltage by default.

No it is a pulse positive and ground (not negative).

But then there anodes are connected to the PWM and the Cathode is connected to ground.

NO NO NO Anodes to +5v cathodes through a resistor to the arduino output.

Ok cool now i'm starting to get it. Thanks. This is the solution i was looking for. Now to get my brain wrapped around it better.

But the digitalWrite there is used only temporarily. Only when the LED initially reaches its brightest does the digitalWrite kick in to turn the LED off then back on again as an indication its at its max brightness. Now if this interferes with analogWrite then i haven't seen it yet since its a temporary event.