Arduino Forum

Using Arduino => General Electronics => Topic started by: gilperon on Nov 16, 2014, 11:40 pm

Title: RGB led: can I put only 1 resistor at ground?
Post by: gilperon on Nov 16, 2014, 11:40 pm
Hi,

I know that if I have an LED I can put the resistor like this:

digital output -> resistor -> led -> ground
AND
digitar output -> led -> resistor -> ground

Both ways above will provide the same amount of current. Ok, I understand that. So why do I need always 3 resistors when using an RGB led? Take a look at this image:

http://www.comofazerascoisas.com.br/posts/arquivos-posts/157/projeto-arduino-led-rgb-06.jpg

In that image (I got it from the post at http://www.comofazerascoisas.com.br/projeto-arduino-controlando-led-rgb-multicolorido.html) the guy uses 3 resistors of 330 ohms each. I understand the reason he used 330 ohms cause this will keep the current under 40mA. But my question is this: why this guy didnt use only one resistor of 330 ohm at the ground?

Why does he use 3 resistors of 330ohm if he could use only 1 resistor of 330ohm conncted to the ground (hi his example latter he will plug all the 3 leds at the same ground, so why not using 1 resistor instead of 3)?
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 17, 2014, 12:10 am
Won't work, need 3 Rs.

1. with just one series-R, when you turn on 2 or more Leds, then the current will split
   2 or 3 ways, and the brightnesses will be lots dimmer than with 3 series-Rs. In the
   latter case, the 3 Leds are effectively totally independent of each other.

2. with only one R, the green and blue Leds will never light, because Vf(orwards) for
   the red led is only 2.1V and it's a much higher 3.5V for the other two, and you have
   all 3 wired effectively "in parallel".

You need to understand "circuit theory" to understand this last statement - so you should go somewheres else and learn about all the basics.

See also some of the posts on this other thread.
http://forum.arduino.cc/index.php?topic=279436.0 (http://forum.arduino.cc/index.php?topic=279436.0)
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: larryd on Nov 17, 2014, 12:49 am
Good stuff here:
https://learn.adafruit.com/all-about-leds?view=all (https://learn.adafruit.com/all-about-leds?view=all)
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Pelleplutt on Nov 18, 2014, 05:21 pm
It is possible to use only one resistor by multiplexing the LEDs.

Turn on red, turn off
Turn on green, turn off
Turn on blue, turn off
Repeat

If varying the on-times you get different colours and brightness.

Pelle
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Grumpy_Mike on Nov 18, 2014, 07:03 pm
Wow what a trade off. All that multiplexing to save two $0.01 resistors.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: larryd on Nov 18, 2014, 07:37 pm
Quote
Wow what a trade off. All that multiplexing to save two $0.01 resistors.
LOL
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Pelleplutt on Nov 18, 2014, 07:54 pm
Wow what a trade off. All that multiplexing to save two $0.01 resistors.
The question was:
Can I only use one resistor?, yes
Nothing about money!

Take two $0.01 resistors, add cost to place them on board, multiply with 100000000 pc = lots of money

If you only make one pc, if it's possible why not do it.

Pelle
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Grumpy_Mike on Nov 18, 2014, 10:21 pm
Quote
if it's possible why not do it.
Cos it is stupid. Can you not see that?
As is this:-
Quote
Take two $0.01 resistors, add cost to place them on board, multiply with 100000000 pc = lots of money
Have you ever designed a mass production consumer electronics product? I have and that argument is not valid.

Nobody makes 100 million of anything. Even if they did what makes you think resistors are as expensive as $0.01 each at this sort of quantity? Have you seen the quotes to have something made with two less resistors? They are identical. To get the brightness the same you have to run the LEDs at a higher current. That will affect the reliability of the circuit and hence the return rate, any notional savings quickly turn into a large loss.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Pelleplutt on Nov 18, 2014, 11:57 pm
I have the last 35 years designed and produced proffesional electronics, all time trying to reduce costs.
It's better with 50 rows of code instead of hardware.
Sometimes I do not have space for 2 resistors, perhaps we can make a solution in software instead.

Whats the problem with multiplexing LEDs, that's made for decades, look at most multidigit displays.
At this forum there are made cubes with multiplexed LEDs, did they burn?
Of course you must check the datasheet for peakcurrent and powerdisipation.

If you ask for a quote, the manufactor counts the number of components, I do it.

It is stupid to say it's stupid when it's possible.

Pelle
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 19, 2014, 02:36 am
Quote
If you ask for a quote, the manufactor counts the number of components, I do it.
This is kind of going off the deep end here. OP is clearly at the stage of needing to learn the basics, rather than build 100,000,000 boards.

Addressing this back to OP = gilperon, the "learning curve" says learn the basics first, then learn the clever hacks after a while. It will take you 2-pennies to solder in 2 additional Rs, and 2-days to figure out how to multiplex a bunch of Leds.

One issue with the RGB Led is the individual Leds have both different Vf as mentioned, and also different brightnesses in the 3 Leds. Typical, Red = 2.1V and 3000 mcd, Green = 3.5V and 5000 mcd, and Blue = 3.5V and 1000 mcd. Normally, people don't care, but having 3 series-Rs allows you to use different R-values and set different currents in the 3 Leds, and therefore compensate for the different brightness characteristics, if you need to.

Quote
I understand the reason he used 330 ohms cause this will keep the current under 40mA.
Also, these things are VERY bright. 40mA is a lot of current for hi-brightness Leds. Even at 10mA, the RGB Leds are so bright they'll bleach your photoreceptors in a couple of seconds at 2-foot distance.

BTW, his 330 ohms at Vcc=5V will drive only (5-3.3V)/330 = 4.5mA into the GB devices, and a little more into the R device. In my currently inprogress project, where the RGB is used as an indicator, I'm cutting the currents back to about 2 mA, just because they are so bright. So, more like 680 ohms.

One other issue is that people will immediately start talking about using extra driver stages, like NPN inverters, etc, in order to offload the Led currents from the processor I/O pins. This was more necessary when driving older Leds that did take 20-40 mA to get adequate brightness, than when using the newer hi-brightness Leds. In my project, I'm driving upwards to 20 indicator Leds, and the current is only in the range of 40-50 mA total, which is no problem for an Arduino chip.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: dlloyd on Nov 19, 2014, 06:04 am
I would connect it like this for a 3 color status indicator and use PWM for intensity control.

To get both colour mixing and intensity control, I think multiplexing 3 PWM signals might not be too difficult. Each PWM signal (R,G,B) could have its own duty cycle range that matches color brightness. When multiplexing sequentially one LED at a time, the other 2 LEDs would be turned off.

(http://i.imgur.com/Cq2M248.jpg)
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 19, 2014, 07:21 am
I would connect it like this for a 3 color status indicator and use PWM for intensity control.

To get both colour mixing and intensity control, I think multiplexing 3 PWM signals might not be too difficult. Each PWM signal (R,G,B) could have its own duty cycle range that matches color brightness. When multiplexing sequentially one LED at a time, the other 2 LEDs would be turned off.
Why do you guys insist on trying to get a beginner (??) to do things the hard way when all he needs is 2 extra 1-penny resistors to do it the easy way. Go look up the concept of the Learning Curve. First you learn the basics, to get a firm foundation in what you're doing. Later on, you can do all the fancy dancy stuff you want.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Grumpy_Mike on Nov 19, 2014, 12:59 pm
Quote
I have the last 35 years designed and produced proffesional electronics,
Glad you never worked for me then.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 19, 2014, 07:26 pm
Be cool, Mike. These guys are not addressing the actual problem that gilperon brought to the thread. Their past lives are irrelevant. 100,000,000 boards is not relevant.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Pelleplutt on Nov 19, 2014, 08:41 pm
http://www.comofazerascoisas.com.br/posts/arquivos-posts/157/projeto-arduino-led-rgb-06.jpg

In that image (I got it from the post at http://www.comofazerascoisas.com.br/projeto-arduino-controlando-led-rgb-multicolorido.html) the guy uses 3 resistors of 330 ohms each. I understand the reason he used 330 ohms cause this will keep the current under 40mA. But my question is this: why this guy didnt use only one resistor of 330 ohm at the ground?

Why does he use 3 resistors of 330ohm if he could use only 1 resistor of 330ohm conncted to the ground (hi his example latter he will plug all the 3 leds at the same ground, so why not using 1 resistor instead of 3)?
I answered gilperon it is possible to use only one resistor if he/she multiplex the RGB LEDs.
Mike started talking how cheap resistors are (they are not free of charge and take place).
Mike told me how stupid I was, well... I'm only a farmers boy but worked with construction and manufactoring electronics for many years. Always optimizing costs for components, assembling and service.

100 million was perhaps a little bit to much but look att the computerindustri if the can eliminating one component.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 19, 2014, 09:34 pm
Quote
I answered gilperon it is possible to use only one resistor if he/she multiplex the RGB LEDs.
That's a nice clever hack, but I figure new people need grounding in the basics first. Secondly, you're trading off using two 1-cent Rs against 2 days or so of coding, especially for a new programmer.

Thirdly, multiplexing makes much more sense if you're using more Leds than you have I/O pins available. Fourthly, it takes quite a lot of cpu cycles to execute proper multiplexing [ie at rates above the flicker-fusion frequency of human vision], and that bites into resources available to do everything else - especially if interrupts are used.

Fifthly, it's easy to simultaneously PWM the 3 channels of the RGB, if separated by 3 Rs, and get 256 hues and 256 or so brightnesses, which is a major reason people use RGBs in the first place. Trying to do this via any multiplexing scheme with only one R would be a real dog to code, and hardly worth the effort [except maybe for bragging rights].

All these things should be explained to a beginner, so they understand the issues on each side.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: rlogiacco on Nov 20, 2014, 12:50 am
I consider myself a beginner and while I do understand it might be simpler to wire 3 resistors I do understand Pelleplut point.
On top of that having a software background for me might be easier to code the PWM rather than walk to the local shop and pay 0.50 for 3 resistors (that's the price I get for low volumes locally).

Now, being a beginner I say the answers "no, you can't" are not making a beginner's life easier, especially when, later on, you start understanding you can do it! If you want to make life simpler to the guy because you think he is a beginner then just say "you can, but it's a lot more complicated than just using 3 resistors and involves some complicated coding we advise against", but when someone else comes in and says "it can be done" then you shouldn't state that he, or his suggestion, is stupid, simply because it's not and it's answering the exact question!

I'm here to learn and I believe Pelletplutt gave his perspective to the question: it's a valid and working solution. The OP never asked for the cheapest solution, and even if he did, it would be a lot cheaper for me to write down the code and use 1 resistor... not everybody has a shelf full of all kind of passives you pros certainly have. And because I've already spent 20$ on my Arduino board and it's sitting there doing nothing I might prefer to have it's loop function doing something better than just running delays over and over.

Now, I'm not saying I would go for Pelleplut's solution, but certainly I do not consider what he said neither stupid nor wrong. It was actually wrong and pretentious to say it was stupid, as much as it is wrong to keep saying it's a less valid solution because of OP knowledge, resource usage and such... the question never mentioned that.

Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 20, 2014, 01:35 am
Well, cool. You can settle one point. See how long it takes to actually code the multiplexing scheme, and I mean actually get multiple LEDs to work in some reasonable way, and not simply code up a simple  for...loop, and say it works.

Easy enough. Now, inject that routine into another program that is doing something non-trivial, that has some other timing constraints, and things start to get more interesting. You're essentially writing your own simple multitasker just to keep your LEDs from flickering.

Now try to change the RGB hues and intensities to given values using your multiplexing scheme, and then report back how much work the 3 programs took to accomplish. Now, you're learning quite a lot by this time.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: polymorph on Nov 20, 2014, 01:50 am
Keeping in mind that, due to all LEDs sharing a single resistor, you cannot have any two LEDs on at the same time. So if you want each color to have a full range of brightness regardless of the other colors states, each can only have a maximum of 1/3 duty cycle.

Which means you will probably need to boost the peak current. As even 40mA is too much to draw from an Arduino pin (never use the full ratings, always derate by 2x or more), you'll need driver transistors. But those require current limiting resistors on their bases.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 20, 2014, 01:57 am
This multiplexing thing all sounds pretty darn simple .... until you actually try to get it to work, and work well. That's the real proof of the pudding.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: dlloyd on Nov 20, 2014, 03:55 am
RGB LED PWM Example (R=25, G=100, B=250):

If using 3 resistors:

Code: [Select]
int pinR = 9;   // LED R
int pinG = 10;  // LED G
int pinB = 11;  // LED B

byte valR = 25;
byte valG = 50;
byte valB = 250;

void setup() {
}

void loop() {
  analogWrite(pinR, valR);
  analogWrite(pinG, valG);
  analogWrite(pinB, valB);
}


If using 1 resistor on GND terminal, RGB multiplexed at 125Hz, 1 extra line of code:

Code: [Select]
int pinR = 9;   // LED R
int pinG = 10;  // LED G
int pinB = 11;  // LED B

byte valR = 25;
byte valG = 50;
byte valB = 250;

void setup() {
}

void loop() {
  byte x = (millis() / 8) % 3;
  analogWrite(pinR, valR * ((x == 0) ? 1 : 0));
  analogWrite(pinG, valG * ((x == 1) ? 1 : 0));
  analogWrite(pinB, valB * ((x == 2) ? 1 : 0));
}
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 20, 2014, 05:19 am
That's actually pretty good, finally an example of something to look at. You've created the makings of a simple multitasker. Now, try interjecting your code into a real program that does something real and useful, as described in reply #18. [or at least trigger this thing off a Timer interrupt].

Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: dlloyd on Nov 20, 2014, 07:15 am
Quote
That's actually pretty good, finally an example of something to look at. You've created the makings of a simple multitasker. Now, try interjecting your code into a real program that does something real and useful, as described in reply #18. [or at least trigger this thing off a Timer interrupt].
Points made in previous replies (re multiplexing) are valid.


Wish I had an RGB led to test ... I just used 3 red LEDs.

The main loop speed of the multiplex code was 97ms for 10,000 iterations on the Arduino Due.


Quote
[or at least trigger this thing off a Timer interrupt].
Would the purpose here be to make the multiplexing immune to blocking code? If so, at this point it's beyond the scope of my experience (looking to correct that when I get the time).


Taking it further, I guess more LEDs could be added like this, but not sure what the practical limit would be:

(http://i.imgur.com/pa8AGbI.jpg)

Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 20, 2014, 08:25 am
Yeah, BlinkWithoutDelay only keeps proper timing if the main loop is never bogged down or delayed by any other code. So, any routines that hog the loop for longer than your led update rate will boggle the led timing, and cause flicker. And as your program grows more complex, the problem will only get worse. You have to scrutinize everything you add to the program.

You can get around this by using a Timer interrupt. Not hard to do, go look in the Arduino reference notes. It's around somewheres. And try here,
http://www.gammon.com.au/forum/?id=11504 (http://www.gammon.com.au/forum/?id=11504)
Just be sure to declare all variables accessed within the interrupt routine as 'volatile'.

The big problem, however, is that every 2 PWM channels also co-opt one timer, and a UNO ATmega328 only has 3 timers. Timer0 is used by millis(). And your 3 RGB analogWrite() calls already use the last 2 timers. So, with a UNO, you're already toast for adding timer interrupts.

For reference: Timer0 PWM on D5,D6. Timer1 PWM on D9,D10. Timer2 PWM on D3,D11.

And also unfortunately, the PWM pins D10,D11 are also used for the SPI peripheral, so that's toast too. Anymore, SPI is one of the most popular peripherals; I use it in every application. And horror of horrors, PWM on pin D10 co-opts Timer1, while PWM on D11 co-opts Timer2. If you want both millis() and also SPI, you lose "all" PWM capability for the 328. [IOW, Atmel REALLY screwed up with their PWM pin assignments on the 328. What a dog].

Other than that, good thinking. It's just that all this is like trying to stuff 25# in a 5# box.


Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Docedison on Nov 22, 2014, 07:53 am
@ oric_dan, well said.
Until you have to go in the field and back up your talk/code you're still playing with paper doilies.
The proof of the pudding, is the way it really works after the first code revision/patch.

Doc
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: dlloyd on Nov 22, 2014, 09:06 am
I've tried this method in four or five examples, and I think a very useful application for this would be a "heartbeat" led for Arduino boards or compatibles. For this application, no timer interrupts required ... we need the RGB to respond to iteration speed.

For fast and smoothly performing code, the led glows white. As the code slows down, some flickering occurs and color changes start becoming apparent. If there's substantial delays, the led will hesitate on a random color.

The user immediately gets a visual picture of the performance of their code.

Here, I've suggested the Arduino board's LED, however an RGB LED gives a much better visual range for main loop speed:
http://forum.arduino.cc/index.php?topic=280201.0 (http://forum.arduino.cc/index.php?topic=280201.0)
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 22, 2014, 08:38 pm
Yeah, it occurred to me the other day, your scheme would make a reasonable indicator for how much time the rest of the program code takes. The more cycles burned, the worse the Led flicker.

But I was hoping you'd come back after 2 days, and have made some progress on getting the multiplexing scheme to actually work. The other guys who were also pushing its merits just disappeared in a puff of smoke.

Basically, it's exactly what I said. People weren't realizing they'd be spending a couple of days getting s.w. to work, just in order to save 2-cents for extra resistors. But it would be a good challenge as a "learning" experience.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: dlloyd on Nov 22, 2014, 09:12 pm
Quote
But I was hoping you'd come back after 2 days, and have made some progress on getting the multiplexing scheme to actually work. The other guys who were also pushing its merits just disappeared in a puff of smoke.
The multiplexing works, but I think you mean "multitasking" (see below)

Quote
Basically, it's exactly what I said. People weren't realizing they'd be spending a couple of days getting s.w. to work, just in order to save 2-cents for extra resistors. But it would be a good challenge as a "learning" experience.
With my experience level at C++ ... could I have more than 2 days please?
I'm on par with this guy who took a lifetime to come up with this (you know, for kids).


(http://i.imgur.com/wi0kjyU.jpg)
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 23, 2014, 04:26 am
Quote
The multiplexing works, but I think you mean "multitasking" (see below)
Well, I don't consider a toy demo to really mean "working". In fact, far too many of the examples that come with Ardunio libraries are just toy demos, and are barely useful for anything.

Quote
With my experience level at C++ ... could I have more than 2 days please?
Well, I would go with the timer interrupts. You just have to make some tradeoffs. Cannot do it all on a UNO-328 as mentioned, so decide what to give up (ie, 1 or 2 pwm channels), and (a) get it to work first. Later on, you can always (b) change the tradeoffs to best advantage.

It would take some wrangling, but you could actually (c) do s.w. pwm on 1 or more channels by varying the timer interrupt occurrence times, but I would just get it to basically work first. Also, you might want to slow down the interrupt rate from every 8-msec. That is hogging a lot of processor time. Eg, a 40-Hz rate is probably adequate to not see flickering, as the human flicker-fusion frequency is about 20-30 hz.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 06:01 pm
Multiplexed PWM for driving a RGB led? Challenge accepted!

Took about 15 minutes to write :)

Code: [Select]

// Multiplexed PWM RGB Led Demo
// By Petri Hakkinen
// 24th November 2014
//
// Arduino driving a single RGB led with only one resistor.
//
// Make the following connections:
// * Connect Arduino pins D2,D3,D3 to anodes of a RGB led.
// * Connect cathode of the RGB led to 330 ohm resistor.
// * Connect the other end of the resistor to ground.
//
// A multiplexed PWM signal is generated by a timer interrupt routine.
//
// Uses TimerOne library, download from here:
// http://playground.arduino.cc/Code/Timer1

#include <TimerOne.h>

volatile uint8_t color[3]; // R,G,B led intensities in range [0,255]
volatile uint8_t phase = 0; // phase of the PWM signal, counts from 0 to 255
volatile uint8_t led = 0; // which led to update, counts from 0 to 2

// Look up table of sin values for mega demo effect.
uint8_t sintab[64];

// The interrupt routine that updates the states of leds.
void interruptRoutine()
{
// turn all leds off
PORTD &= B11100011;

// sample pwm and turn on one led
if(phase < color[led])
PORTD |= 1<<(led+2);

led = (led + 1) & 3;
phase++;
}

void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);

// attach interrupt routine
Timer1.initialize(50);
Timer1.attachInterrupt(interruptRoutine);

// init sin table for mega demo effect
for(uint8_t i = 0; i < 64; i++)
sintab[i] = (uint8_t)(sin(i * M_PI * 2 / 64) * 127.0f + 128.0f);
}

void loop()
{
const uint8_t speed = 13;

color[0] = 0;
color[1] = 0;
color[2] = 0;

// fade red
for(int i = 0; i < 256; i++) {
color[0] = i;
delay(speed);
}

// fade green
for(int i = 0; i < 256; i++) {
color[1] = i;
delay(speed);
}

// fade blue
for(int i = 0; i < 256; i++) {
color[2] = i;
delay(speed);
}

// mega demo effect
for(int i = 0; i < 500; i++) {
color[0] = sintab[i & 63];
color[1] = sintab[(i*2 + 123) & 63];
color[2] = sintab[(i*2/3 + 35) & 63];
delay(speed);
}
}
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 24, 2014, 06:45 pm
Cool, something new to look at, :-). A couple of quick comments while mulling things over.

1. did you also include the time it took to think about what you needed to do [ie, "design
   time"], plus to do background research [eg, to find Timer references], in your 15-minutes?

2. one problem - you can't have 15-msec delays in your main loop, that'll kill the efficiency
   of your overall program.

The whole point of the exercise is to get multiplexing to work in the context of a "real" program that does something productive, and not just a "demo", as mentioned previously. But, new inputs are always good!
   
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 06:55 pm
Thanks!

1. I didn't take time, but I estimate about 15 minutes planning, 15 minutes implementation.

2. The main loop is just a demo showing that generating the PWM signals don't block the CPU and that the PWM update frequency is independent of the main program. I.e. adding new stuff to the main program does not make the LEDs flicker, a concern that was raised earlier in this thread.

btw. how would you define a "real program"? I think this technique is pretty general and can be used by any program that can yield one timer interrupt for the LED update routine.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 07:22 pm
To further elaborate: the point of the sketch I did is that you can rip out the entire main loop and replace it with the "real program". The main program can change the values in the color array at will. The interrupt routine is the real beef and takes care of generating the multiplexed PWM signals based on the R,G,B values stored in the array.

You can adjust the update frequency by adjusting the timer period here:
Code: [Select]
Timer1.initialize(50);
Larger values use less CPU time.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 24, 2014, 07:24 pm
ok, will take me a bit of time to figure out the code.

A real program would be something more than a simple demo, but where the multiplexing scheme might be inserted for monitoring ongoing processes. Eg, something that uses libraries, which tend to be cycle hogs. An example might be reading multiple A/D channels, buffering and formatting the data using sprintf() statements into a nice ASCII string format, and then writing to an SD card.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 07:35 pm
ok, will take me a bit of time to figure out the code.
Ok, I will happily answer any questions.

A real program would be something more than a simple demo, but where the multiplexing scheme might be inserted for monitoring ongoing processes. Eg, something that uses libraries, which tend to be cycle hogs. An example might be reading multiple A/D channels, buffering and formatting the data using sprintf() statements into a nice ASCII string format, and then writing to an SD card.
Sounds doable. I'll leave the details for you to fill out :)

Here's the code with "demo parts" ripped out if you want to try plugging in the stuff you mentioned above.

Code: [Select]
#include <TimerOne.h>

volatile uint8_t color[3]; // R,G,B led intensities in range [0,255]
volatile uint8_t phase = 0; // phase of the PWM signal, counts from 0 to 255
volatile uint8_t led = 0; // which led to update, counts from 0 to 2

// The interrupt routine that updates the states of leds.
void interruptRoutine()
{
 // turn all leds off
 PORTD &= B11100011;

 // sample pwm and turn on one led
 if(phase < color[led])
 PORTD |= 1<<(led+2);

 led = (led + 1) & 3;
 phase++;
}

void setup()
{
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);

 // attach interrupt routine
 Timer1.initialize(50);   // PWM update period here, make it larger if your program needs more CPU time
 Timer1.attachInterrupt(interruptRoutine);
}

void loop()
{
  // <insert your code here, write the intensities of LEDs to color array >
}
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 24, 2014, 08:36 pm
I'm not familiar with the TimerOne library. To get this straight,

1. you didn't actually write a multiplexing routine [from scratch] in 15-minutes, you found someone else's library that generates s.w. PWM using timer interrupts? LOL, good one.

2. initialize(50) means it's actually generating a timer interrupt every 50-usec, or 20,000 times per sec?

I imagine that's not overly loading down the AVR chip, but it's still a lot of interrupts. Luckily, your interrupt routine code is fairly short. I think one might need to do a fair amount of testing to determine whether all those interrupts might impact other processing in a "real" program. OTOH, you probably don't really need 8-bit PWM for Led intensities, so the interrupts could probably be slowed down by quite a bit. Does this sound right? I'm just trying to analyze what's going on here.

Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 08:56 pm
1. I feel you are trying to downplay my contribution :) TimerOne library is only used to attach the interrupt routine. I could have setup the interrupt myself, but why reimplement the wheel? The details of the multiplexed PWM generation is in the interrupt routine I posted. I.e. TimerOne library is not used to generate the PWM signal, because it can not generate a multiplexed PWM signal.

2. I already mentioned that you can change the timer interrupt frequency. 50 is just a value I threw in. You can use a higher value to slow down the update frequency if it matters in your application.

The number of steps needed depends on the application. It's easy to change. For example, change "phase++" to "phase = (phase + 1) & 63" and use color intensities in range 0-63 for 6 bits.

I suggest you wire this up, shouldn't take more than a few minutes and play around with the code.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 24, 2014, 09:10 pm
Sorry, like I said, I am unfamiliar with TimerOne, so just trying to figure out what is going on here. You said to ask questions [:-)]. Ok, now I see you're doing all the pwm'ing inside the interrupt routine, but I think you need the very high interrupt rate to get good 8-bit PWM.

Quote
For example, change "phase++" to "phase = (phase + 1) & 63" and use color intensities in range 0-63 for 6 bits.
I think you could use phase+=4; and initialize(200) to get the same effect, although it may still be adequate [ie, no flickering] at even slower interrupt rates.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 09:11 pm
And to answer your question: yes, if you lower the number of PWM bits, lets say from 8 bits to 4 bits, so that phase counts from 0-15 instead of 0-255, the PWM loops x16 times faster. In this case you could increase the interrupt period by a factor of 16 without affecting the update frequency.

Also I believe that you can increase 50 in any case (even with 8 bits), I just didn't test with other values.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 09:12 pm
I think you could use phase+=4; and initialize(200) to get the same effect, although it may still be adequate [ie, no flickering] at even slower interrupt rates.
Yes, that would work too, same effect.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 09:26 pm
Tested with "phase += 2" (7 bits resolution) and "Timer.initialize(175)" and seems to work well.

Less than 6 bits is probably not sufficient for slow smooth fades (depends what you want really).

Also if we are talking about optimizations, I would try to squeeze every cycle out of the interrupt routine. Writing it in assembly and getting rid of TimerOne library and its interrupt call overhead would help.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 24, 2014, 09:34 pm
All in all, pretty darn good solution.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 09:38 pm
All in all, pretty darn good solution.
Thank you!

I have to give you credit for criticizing the CPU usage. I admit the high interrupt rate can be a problem for CPU heavy programs.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 24, 2014, 10:24 pm
Well, the idea is to try and look at these things from every which angle, isn't it. That's why this thread didn't die after 2 replys, :-). These are good problems to solve.

Also, I just thought to compute the actual update rate. With initialize(50) --> 20,000 interrupts/sec, for the original 8-bit PWM, that's 20000/256= 78 Hz. Divided by 3 Leds gives 26 Hz updates, which would probably result in quite perceivable flicker. OTOH, dropping to 5- or 6-bit PWM and using initialize(100) rather than initialize(200) would lessen the interrupt overhead and should still keep the PWM frequency up at 50 Hz or more, and which would be fine.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: Pelleplutt on Nov 24, 2014, 10:29 pm
. The other guys who were also pushing its merits just disappeared in a puff of smoke.

I'm still here reading what you are writing.
Thanks Petri

Pelle
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: ph77 on Nov 24, 2014, 11:48 pm
I didn't notice any flickering. Note that even at 25-50hz the led is not flickering completely on/off, it's changing color at that frequency r->g->b->r... Etc. Brain is not so sensitive to hue flickering.

Unless of course the color is 255,0,0 or something similar.

Ok, I'm off to bed now, past midnight here. Later!
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: oric_dan on Nov 25, 2014, 03:01 am
Flickering doesn't mean completely on-off, it means perceiving a noticeable change in intensity. It may actually only be a few percent to be noticeable. This is why the AC mains use 50-60 Hz. Below that people perceive flickering, and it's very distracting.

This shows that a 1% voltage fluctuation is generally perceivable. It's not a hard threshold, much more complex than that.
http://zone.ni.com/reference/en-XX/help/373375D-01/lveptconcepts/ep_light_flickers/ (http://zone.ni.com/reference/en-XX/help/373375D-01/lveptconcepts/ep_light_flickers/)

Ok, tomorrow you can fix your code. Hint: what's the maximum duty cycle each of your Leds can have in the existing code? [I may be wrong, but think it's 33%]. Hint: the "fix" is duplicating line 2 of your ISR twice more.
Title: Re: RGB led: can I put only 1 resistor at ground?
Post by: dlloyd on Nov 25, 2014, 05:12 am
Had another idea for an RGB heartbeat indicator.

●  Demultiplexing millis() for R,G,B using digitalWrite.
●  The single resistor is returned through one PWM pin to set a stable intensity.
●  As iteration speed slows, intensity remains constant eliminating flicker.
●  Also, as iteration speed slows, perceived color varies, then jumping from color to color becomes apparent.
●  Very low cpu cycles required, especially if direct port manipulation is used.
●  No libraries or interrupts required.

(http://i.imgur.com/TKGsaRh.jpg)

Code: [Select]
int ledG = 8;   // LED Gnd
int pinR = 9;   // LED R
int pinG = 10;  // LED G
int pinB = 11;  // LED B

const byte intensity = 120; // 0 = off, 255 = full intensity

void setup() {
  pinMode(pinR, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(pinB, OUTPUT);
  analogWrite(ledG, (255 - intensity)); //PWM
}

void loop() {
  byte x = (millis() / 8) % 3; //125ms demultiplexer
  digitalWrite(pinR, 1 * ((x == 0) ? 1 : 0));
  digitalWrite(pinG, 1 * ((x == 1) ? 1 : 0));
  digitalWrite(pinB, 1 * ((x == 2) ? 1 : 0));
}