Bela
Real-time, ultra-low-latency audio and sensor processing system for BeagleBone Black
|
Bicolor LEDs often come in a package with two terminals only. Internally, the LEDs are connected back-to-back with opposite polarity. By using a tri-state pin and a PWM generator, you can dim and mix each color at will. A PWM channel can be shared across multiple LED pairs, as long as it provides enough current. In this example we control 8 LEDs (or 4 bi-color LEDs) using a single PWM generator and 4 tri-state GPIOs.
Wiring: from each GPIO channels, add a 100ohm series resistor and then connect two LEDs back-to-back with opposite orientation from the resistor to the PWM output.
Remember that PWM oscillates between HIGH
and LOW
at a high rate. LED0 turns on only when GPIO is LOW
. LED1 turns only when GPIO is HIGH
. When GPIO is set to an INPUT
, it goes to high impedance and acts as an open circuit, therefore both LEDs are off.
Bela allows to switch GPIO between OUTPUT
-HIGH
, OUTPUT
-LOW
, INPUT
for every sample at 44.1kHz. For instance, to control the brightness of LED0 we can set an arbitrary period
and set GPIO to OUTPUT
-LOW
for a number of samples (<= period
) proportional to the brightness, setting it to INPUT for the remainder samples. If we keep it to OUTPUT
-LOW
for the whole period
, it will have the maximum brightness, if we set it to INPUT
for the whole period
, it will be dark. Intermediate values will produce intermediate brightness levels. Similarly for LED1, except that we would alternate between OUTPUT
-HIGH
and INPUT
.
Larger values of period
allow for more resolution for the dimming, however if the value gets too large, you may have visible flickering.
As we need to control both LEDs from a single GPIO pin, we decide to alternate between the two LEDs for every sample, so that during even samples we control LED0 and during odd samples we control LED1. This way, for even samples the GPIO can only be OUTPUT
-LOW
or INPUT
; for odd samples it can only be OUTPUT
-HIGH
or INPUT
. The balance between OUTPUT
-LOW
and INPUT
on even samples controls the brightness of LED0, while the balance between OUTPUT
-HIGH
and INPUT
on odd samples controls the brightness of LED1. This way we can have independent control over the brightness of two LEDs with a single tri-state GPIO + a shared PWM generator.
When using a hardware PWM generator, this switches at a very high frequency, many times per sample. If this is not available, we can use a software PWM generator, toggling one of Bela's digital outputs. For this to be effective, the GPIO needs to hold the state for at least one full PWM period. We toggle the soft PWM output every sample (generating a 50% pulse wave at context->digitalSampleRate / 2
Hz), therefore we need to hold the value of an LED for 2 samples.
Varying the duty cycle of the PWM generator allows to balance between the different brightness of different colors of LEDs. However, to achieve this with the soft PWM, you would need to slow down the frequency of the pulse wave. This would in turn lower the resolution of the dimming, unless the period
is increased, again with the risk of causing visible flickering.
When useSequencer = true
, then analogIn0 affects the speed of the steps and analogIn1 affects the overall brightness. When useSequencer = false
, then each of the analogIns affects the brightness of the corresponding LED.
To use a hardware PWM, e.g.: on P9_14:
otherwise you can use soft PWM using the Bela digtal specified in the code.
Also, you will need your pins
not to have any pull-up or pull-down (0x2f
) otherwise they may be lightly dim when they should be off.