RGB LED colours not displaying correctly

I've put together a piece of code that switchs between different values of an RGB LED when I press a button. However, when assembled and running the LED displays light blue, light purple and yellow/slightly green for the current values rather than the expected red, green and blue - it works fine when testing off the board and I don't know why the colours would change. Any ideas? I'm currently running the code on a "Pro Mini" Atmega328 3.3V board.

#include <PushButton.h>

int count = 0;
int redPin = 7;
int greenPin = 6;
int bluePin = 5;

#define BUTTON_PIN 2

PushButton LEDbutton(BUTTON_PIN);

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  LEDbutton.setDebounceTime(50);
  LEDbutton.setActiveLogic(LOW);
}

void loop() {
  LEDbutton.update();

  if (LEDbutton.isClicked()) {
    count = count + 1;
  }
  if (count == 0) {
    setColor(255, 0, 0); // Red Color
    delay(100);  
  }
  if (count == 1) {
    setColor(0, 255, 0);  // Green Color
    delay(100); 
  }
  if (count == 2) {
    setColor(0, 0, 255);  // Blue Color
    delay(100); 
  }
  if (count == 3) {
    count = 0;
  }
}

void setColor(int redValue, int greenValue, int blueValue) {
  analogWrite(redPin, redValue);
  analogWrite(greenPin, greenValue);
  analogWrite(bluePin, blueValue);
}

Would this be a common anode or common cathode RGB led?

Please post a schematic so we can see how it's connected to the Arduino.

Pin 7 is not a PWM capable pin on a Pro Mini. Red values below 128 will set the output low, at 128 above will set the output high.

1 Like

I did just see that when looking for results - I'll try switching to pin 9 or 3 and see what happens.... edit: moved it over to pin 9, but unfortunately didn't affect anything

Should've mentioned, it's a common anode LED with the anode connected to 5V on the board and each other led connected to the specified pins in the code via a 220 ohm resistor.

That's called "cyan". It's a mix of blue & green, the optical opposite of red.

"Magenta", the optical opposite of green

Yellow is the optical opposite of blue.

Conclusion: your LED is displaying the opposite colour to what you expect, which can happen if you don't understand how to use a common anode RGB led.

Try this:

void setColor(int redValue, int greenValue, int blueValue) {
  analogWrite(redPin, 255 - redValue);
  analogWrite(greenPin, 255 - greenValue);
  analogWrite(bluePin, 255 - blueValue);
}
3 Likes

You need a higher value for the red pin of the RGB led in order to get more accurate colours. Try 330 or 470 ohm. This is because the forward-voltage of the red LED is around 1.8V compared to the 2.8~3.2V of the green and blue LEDs.

1 Like

Thanks for the help! I did think the solution would be something along those lines as the displayed colours did seem to be mirrored. All working as expected now! I was aware of the need to use a different resistor for the red pin, just had some 220 ohm ones to hand to try it out for now.

But do you understand why the original code was wrong and the updated code fixed it? If not, please ask.

So, I understand the values where inverted and the current reading of 255 minus the given value now displays the opposite and expected colour, but not why they were inverted in the first place.

They are inverted because you are using a common anode RGB LED. The current to light the led comes from (sourced from) the 5V and goes to ground though (sunk by) the PWM pins.

The PWM pins can sink current when they are LOW and can't sink current when they are HIGH.

analogWrite(pin, 0) makes the pin LOW all the time, and allows it to sink maximum current, making the LED bright.

analogWrite(pin, 255) makes the pin HIGH all the time and never allows it to sink any current, so the LED is completely off.

1 Like

Got it, thanks for the explanation!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.