Electronic – Control multiple LEDS with one PWM pin

ledpwm

I have a circuit that has 4 LEDs that are controlled by a microcontroller. Only one LED needs to be illuminated at a time. I would like to be able to control the brightness of the LED that is on via pulse-width modulation however I only have one PWM pin available. I do have 4 standard GPIO pins available though. I am wondering the circuit that I have drawn below would work?

I would configure GPIO 1 as an open-drain output and set up the PWM on it to control the brightness. Initially, to turn both LEDs off, I would configure GPIO 2 and 3 as push-pull outputs and drive them high. My thought it that this would put 3.3V on both sides of the LEDs thus preventing current from flowing through them. Then if I wanted to turn on LED1 I would just configure GPIO2 to float.

My guess is that I will have problems with the amount of current that is being sunk into GPIO1 if I did this with 4 LEDs. But I'm not sure?

Would this circuit or something similar work or do I need to add transistors to pull this off? The micro is a PIC24F if that matters.

enter image description here

Best Answer

Charlieplexing my friend.

You simply hook them up like this:

enter image description here

Then you write high and low on the different pins which will activate individual LED's.

Let's say you want LED3 to light up, then you set it up like this:

Pin1 = INPUT //high impedance
Pin2 = OUTPUT(1)
Pin3 = OUTPUT(0)

If you want Led3 to be 50% bright, then implement a PWM in software.

Pin1 = INPUT //high impedance
Pin2 = software_pwm(0.5)
Pin3 = OUTPUT(0)

And if you want all 4 to light up (I assume that you don't connect LED5 and LED6)

Then it will look like this:

while(1){

    //LED1
    Pin1 = OUTPUT(1)
    Pin2 = OUTPUT(0)
    Pin3 = INPUT  //high impedance
    delay_some_milliseconds()  
    //we don't need to be flashing at 500khz, or whatever high
    //frequency we'll get without any delays, 60Hz is good enough,
    //some ms will bring you down there. 

    //LED2
    Pin1 = OUTPUT(0)
    Pin2 = OUTPUT(1)
    Pin3 = INPUT
    delay_some_milliseconds()

    //LED3
    Pin1 = INPUT
    Pin2 = OUTPUT(1)
    Pin3 = OUTPUT(0)
    delay_some_milliseconds()

    //LED4
    Pin1 = INPUT
    Pin2 = OUTPUT(0)
    Pin3 = OUTPUT(1)
    delay_some_milliseconds()
}