Simplest way to control 2 independent LEDS through PWM on single PIC?

Thread Starter

Subterranean

Joined Jul 27, 2010
13
I'm currently designing a simple project using a PIC to control the brightness of two separate LED's. Because they are power LEDs I need extra power management IC's in between but I have all that sorted already so you can just think about the PWM directly controlling the brightness.

My question is what is the simplest PIC I can use to do this easily? Ideally I would like to use a 8-pin PIC due to space constraints but no 8 pin PICs that I can see from Microchips selection tool have more than 1 PWM channel. I was looking at the Half-Bridge ability of the ECCP module, but I think I'm right in saying this would not be useful to me if I wanted both LEDs to be on over 50% duty cycle (70% and 90% for example).

So, given that the PICs entire life will be spent doing PWM and looking for 2 inputs to change, to change the duty cycle which could be done with interrupts, would the best way be to use the 1 PWM channel, and a 'software PWM' that I program as described in the sticky thread at the top. Would this work fine without being a total pain to program?

Any other thoughts or advice is greatly appreciated.
 

MMcLaren

Joined Feb 14, 2010
861
I would use a 12F617, a 12F635, or a 12F683 because they have an 8-MHz internal oscillator instead of a 4-MHz internal oscillator, which can provide higher refresh rates. You can run the internal oscillator on the much newer 12F1822 at 32-MHz.

Do you need to control the duty cycle of both LEDs independently? If so, wouldn't you need four switches, two 'up' switches and two 'down' switches?

Anyway, you should be able to do 8 bit (256 step) PWM on both LEDs at reasonably high refresh rates using software PWM but due to the non-linear nature of PWM brightness control I would recommend implementing 6-bit (64 step) gamma correction for smoother and more linear brightness level changes. I would not recommend using the soft PWM method in the sticky at the top of this Forum.

I did a similar project earlier this year using a Sony SIRC remote (instead of six switches) to independently control the brightness of three medium power LEDs (using 64 gamma corrected steps or brightness levels spanning the 8 bit soft PWM range).

Happy Holidays. Mike...
 

Attachments

Last edited:

thatoneguy

Joined Feb 19, 2009
6,359
The PIC ECCP PWM ports are geared more towards driving an H-Bridge/motor than driving LEDs.

Software PWM is sufficient. What will determine the brightness of the two LEDs?
 

Markd77

Joined Sep 7, 2009
2,806
I'd use software PWM for both, it makes things easier. I get about 200 Hz easily enough with 256 level dimming of 2 LEDs on a 12F675 at 4MHz.
It could go faster with a bit of optimisation but that seemed decent enough.
This is the important bit - as you can see I don't really do comments, but hopefully it is fairly self explanatory.
In the below form it doesen't work for zero brightness, but I didn't need it.
Rich (BB code):
loop
    decf count, F
    bcf GPIObuffer, 0
    bcf GPIObuffer, 1
    movf count, W
    subwf redduty, W
    btfsc STATUS, C
    bsf GPIObuffer, 0
    movf count, W
    subwf blueduty, W
    btfsc STATUS, C
    bsf GPIObuffer, 1
    movf GPIObuffer, W
    movwf GPIO
 
    goto loop
 

MMcLaren

Joined Feb 14, 2010
861
Hi Mark,

That's really very decent code. I'm kind of a stickler about having a true 0% duty cycle though. It's amazing how much light an LED will throw off even at a measly 1/256th duty cycle. An LED with a 0% duty cycle really should be fully off.

If you're interested, here's something similar but about 25% faster;

Rich (BB code):
loop
        movf    led+0,W         ; led[0] duty cycle, 0..255       |B0
        subwf   dcy,W           ; C = (led[0] >= dcy)             |B0
        rlf     shadow,F        ;                                 |B0
        movf    led+1,W         ; led[1] duty cycle, 0..255       |B0
        subwf   dcy,W           ; C = (led[1] >= dcy)             |B0
        rlf     shadow,W        ;                                 |B0
        xorlw   0x03            ; for active hi outputs           |B0
        movwf   GPIO            ; update LEDs on GP1 & GP0        |B0
        incf    dcy,F           ; bump duty cycle counter         |B0
        goto    loop            ;                                 |B0
You would still need code within the loop to sample switches. And if you're using a loop instead of interrupts, like I do in the Sony SIRC RGB Accent Light Controller demo, you really should be writing the code so that you end up with an isochronous loop (no duty cycle or period jitter).

Happy Holidays everybody.

Cheerful regards, Mike
 

thatoneguy

Joined Feb 19, 2009
6,359
You could use a 12F, or even a 6 pin 10F series PIC with the routines above.

It mostly depends on what determines the brightness, e.g. is ADC needed?
 

Thread Starter

Subterranean

Joined Jul 27, 2010
13
Thanks for the replies, and especially the code snippets, they will help a lot.

As for how the brightness of the LEDs is determined, the PWM signal controls a number of AMC7135 low dropout current regulators in parallel (datasheet here). This way I dont need to worry about measuring any voltages or currents, the duty cycle controls the brightness directly.

The hardware I'm fitting this project into only has two switches (actually one single 2 pole switch); so each change will have to just cycle through a number of set brightnesses for each led. I have thought about a 'programming mode' to allow the brightness modes to be changed and save them to eeprom (another factor I will have to think about when choosing a PIC) but it all gets a bit complicated, and will take a bit of thinking about how to make it user friendly given I only have 2 switches for input, and 2 leds to indicate whats happening. I was thinking possibly using a small pot/trimmer (meaning i would need an ADC) to choose precise brightness settings but like I say this is getting a little complicated.
 
Last edited:
Top