Uno R3 controlling RGB LEDs

Hi everyone,
I have a Uno R3 starter kit, and I am working on a project that does multiple things. Eventually I would like to have a touchscreen GUI similar to a Programmable Logic Controller's HMI to interact with a Uno and a Mega 2560. Currently though, I have been trying to work with RGBs. After much time looking over wiring, and learning more code, I realized that they were Common Anode. I figured out how to get basic red, green, blue and white after fiddling around with digitalWrite and analogWrite, but there comes the problem. The color combinations of 0-255 are backwards where 0 is full on. I was trying to get orange and yellow, but all combinations I find online do not match, and it ends up being a red and green mix where you can see both colors. I have tried with different backlighting and in the dark, and it still appears not right. I am using 330 Ohm resistors for each Cathode and have 3 RGBs in parallel, but still cannot get anything that appears close to orange or yellow. I am not posting code at this time, because all it contains is declaring pins for output, and writing values for the Cathode back to the Uno. Any suggestions will be greatly appreciated.

Lance

Hi, how have you got your LEDs wired?
Can you please post a copy of your sketch, using code tags.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

This way we can see how you have your connections.
Please no FRITZing type diagram.

Tom.... :slight_smile:

Could you reverse the PWM effect by using (255 - desired_value) so that 255 = full on, and 0 = full off?

Lance1985:
I was trying to get orange and yellow, but ... it ends up being a red and green mix where you can see both colors.

Hi Lance, this is how all rgb leds work. Any colour is made by mixing red, green and blue, those are the only colours the led actually makes. From a distance, the eye is fooled into seeing other colours, but up close you will see them as separate red, green and blue. Look closely at the screen of a tv or monitor with a magnifying glass and you will see the same thing. If you need to see mixed colours up close, you must place an object in front of the led to diffuse the light. For example drill a small hole in a table tennis ball and insert the led into thd hole.

Paul

Try roughing up a piece of clear plastic (piece of plastic bottle) with fine sandpaper and see if the led light blends in that, or maybe use tracing paper, something translucent/frosted.

Here's a sketch showing what ~ does to bytes.

void setup( void )
{
  Serial.begin( 115200 );
  Serial.println( );
  
  byte b;
  for ( int i = 0; i < 256; i++ )
  {
    b = (byte) ( i & 255 );
    Serial.print( (byte) b ); // had to cast byte to (byte) because print wants to make a long!
    Serial.print( "  " );
    Serial.println( (byte) ~b ); // ~ is bitwise not, inverts all the bits
  }
}

void loop( void )
{
}

it ends up being a red and green mix where you can see both colors.

Yes as PaulRB says you need a diffuser.

Another way is to use very fine sand paper and rub the LED cover to act as a diffuser. Or you can put a piece of polyester drafting film over the LED.

The ping pong ball works very well and you can do as PaulRB says or you can cut one in half and mount it over the LED. Like in the picture attached. This project also has a push button so these are illuminated keys.

//OUTPUT PINS
const int green = 8;
const int red = 10;
const int blue = 12;
int value = 0;

//SET AS OUTPUT
void setup () {
  pinMode (green, OUTPUT);
  pinMode (red, OUTPUT);
  pinMode (blue, OUTPUT);
}

//START PROGRAM
void loop() {
  analogWrite(green, 0); 
  analogWrite(red, 102);
  analogWrite(blue, 255);
  delay(200);
}

This is my code. I have not gotten a ping pong ball yet to try that, but using tracing paper only made the red appear as a ring and the green a solid circle. I have 2 photos of the circuit. Please forgive the bad quality, computer photography was never my best. I do not have CAD, but I can make a Visio representation in a day or so. In case the photos are not clear enough, the pins used are 9-R, 10-G, and 11-B, and +5V for the Anode, with all three jumpered in parallel.

but using tracing paper only made the red appear as a ring and the green a solid circle.

Then the tracing paper must be placed further away from the LED.

However those types would benefit from the sandpaper treatment.

Thank you to everyone for the assistance. I have not tried the sandpaper yet. Would buying diffused Common Cathode be simpler, code wise? I may not be a expert with programming and electronics, but I'm learning and trying.
Thank you again everyone.
Lance

Would buying diffused Common Cathode be simpler, code wise?

Makes no odds to the code, this is simply a mechanically diffusing issue.

That example I posted will show you how to handle the values. Just send them inverted.

byte B = 255;

~B is 0.

It works for every value of B. So instead of B, use ~B which I think the invert takes 1 cycle.

You can invert constants but you have to cast them as type byte or the compiler will make an int.

Thanks GoForSmoke, that was what I was trying to figure out. I thought that the Common Anode was complicated because of the reversing of the Hex RGB values. Thank you everyone else, including Grumpy_Mike, it seems to work fine now. The color wasn't as blatant as I thought it would be. I thought it would be the equivalent of a specific single color LED.

Lance

Take this as a cue to get into bit logic. It is high value knowledge.

Every byte is an array of 8 T/F data. And int has 16 (unsigned or signed, the high bit acts differently on right-shift) and longs have 32.

You can use whichever ones you want or all at once.
You can operate on the bits of one byte with another 1:1 very quickly by using bitwise logic.

The value of the byte will tell you about all of the bits together.
And that with a mask and select just the bits you want to matter, the result tells you about those.

if ( this && that && T/F || T/F || T/F && yet another T/F, etc, etc ) statements can be reduced to filling a variable with bits and using a switch-case or maybe just one if() to code.

I store previous and current pin reads in the same byte instead of 2 variables. The current read is in bit 0 and the previous is in bit 1. The value of that byte tells me if the pin state changed.

Value 0 is low-low, no change. 1 is high-low, a low to high change, 2 is low-high and 3 is high-high.

I don't need two variables to detect pin change, just one byte and I have room to include other factors in that same byte. My code can be cleaner, faster and use less RAM. Is that worthy?

BTW, keep looking for better diffusers. I bought RGB's from Yourduino at 5/$1. Maybe I should try covering the ends of some with wax or glue instead of roughened plastic? I can lose a few out of the bag.

Hi everyone,

I have been busy, but I got it to work with all colors. I tried to switch to a Mega 2560 to get more I/O. It was working, but now all digital pins are reading and causing the RGB LEDs to light, even if I did not declare them. Did I blow something or mess it up? I wired it the same as with the Uno, with +5v going to the Anode, and a 330 Ohm resistor at the Cathodes before going to the pins. It uses the same wiring as the Uno, I just changed it to the Mega and even reused the same code and pins.

Thanks for any help,

Lance

Lance1985:
Hi everyone,

Did I blow something or mess it up?

Hard to tell. The Mega does have more PWM capable pins than the Mega, maybe you were using the wrong pins on the Uno?

I just noticed that there is a selection for type of board, I never noticed it before. It might fix it, but I have to wait to try it again.
Lance

I think you got it right there, Mike.

UNO PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.

And the code above:

//OUTPUT PINS
const int green = 8;
const int red = 10;
const int blue = 12;

You had red varying evenly but green and blue were OFF or ON. Does it look nice anyway?

MEGA PWM: 2 to 13 and 44 to 46. Provide 8-bit PWM output with the analogWrite() function.

Has the code changed much?

No, the code was much the same. I added some more pins for using some RGBs separately instead of in a parallel circuit. The selection to the Mega board did the trick. So, all is well now. I think I will keep this topic open in case I have more questions in relation to the project.

Also, I was wondering about relays. I understand that some relays can have their coils driven using Arduino, but all my pins seem to run as the ground of the circuit. I noticed that if plugging in a wire to the +5V to give power to the RGBs, if I plug a wire into the ground it shuts off the board. I noticed this on both the Uno and the Mega. I was wondering if this was a common issue, and also can a relay coil circuit be run with the +5V through the coil to the pin on the Arduino? I don't know if either of those make sense, but I thought I would ask.

Lance

Yes, you can find 5V relay coils that are low enough current to be driven direct from an Arduino pin. Be sure to have a diode across the coil.
This board I made with an Atmega1284 for example drove 15 telecom relays to simulate button presses on a piece of equipment.

(last time I did a board without solder mask too - had to be soooo careful soldering to avoid ground plane shorts with the 10mil trace clearances!)