Controlling many LEDs (extra analog pins?)


New member

Disclaimer, I am quite new to the embedded world.

I have a Teensy 4.1 and I want to control the RGB leds in several of these buttons. In total I have six buttons. Since they are common anode each buttons has three wires corresponing to the RGB leds that I need to control. This results in 6*3=18 analog pins needed. Since I am already using several pins for other things, I do not have enough pins for this.

I have looked at several potential solutions. I have seen some people use multiplexers, however this does not work in my case since I need to control them all at the same time? I have also seen DACs, however I have only found modules with a low amount of extra pins. I would prefere something like 16 extra analog pins.

Another question is that the LEDs in the button can use the 3.3v from the Teensy, however they could also be powered with higher voltages like 12V it says. How would I go about this?

Is there perhaps a module or similar that would do both of these for me (reduce the amount of pins needed from the Teensy and power the LEDs with 12V)?

Just a thought: I bet there’s some external chip (SPI or I2C) you could use to drive many LEDs.
The SoftPWM library might help. It's one of the many libraries automatically installed for Teensy, so just look for it in the File > Examples menu to get started.

On the hardware question, as I understand the info from Adafruit's page, you probably won't gain anything by using 12 volts. The LED+resistor is rated for 6 volts maximum. Adafruit says to add another resistor if you use 12 volts. I don't understand why they recommend the same resistor for either 12V or 24V. Presumably you would want to adjust the resistor value so you get close to 6 volts across the LED+resistor inside the pushbutton and the other 6V across the resistor you've added.

Using 5V won't be quite as bright as 6V, but might be good enough and could be relatively easy since you could just use a buffer chip like 74ACHT125 to convert Teensy's 3.3V outputs to 5V. Because you already have 5 volts you're using to power Teensy, 5V power is probably pretty convenient. (but do check if it's rated for enough to power up so many LEDs)

To use 6V, of course you'll need a 6V power source as the first step. You could probably connect a NPN or N-channel transistor (base or gate) to each PWM pin. The emitter or source would connect to GND. Then you'd connect each LED cathode to the collector or drain pin. If using NPN or a "large" mosfet (any not specifically mentioning compatible with logic signal drive), you need a resistor between Teensy's pin and the transitor base/gate pin to limit the current. Use between 2.2K to 10K.
Thank you for your advise.

I guess it should be sufficient with 5V for the LEDs then, or even 3.3V (I do not care that much about the brightnes). As I understand it the 74ACHT125 has four level shifters. Therefore, I could power 4 LEDs from this one chip?

The SoftPWM library seems to be very useful in my case. However, I am still not sure if I have enough pins. I am using at least 12 pins for controlling servos and several others for buttons and switches. I intend to use the MCP2307 to add some digital pins for the buttons and switches. I guess I cannot use the SoftPWM library on these pins?

I can see that there also exists some pwm modules, like PCA9685. I guess I could move my servos to this module and use the freed pins on the teensy for the LEDs?

Another option I have seen is MAX7219 or similar. It says that these should be able to power up to 64-leds using a matrix layout. It only require SPI pins. Would this also work?

Again, thanks!
Confirm, SoftPWM only works with the normal pins. It doesn't support MCP23017 or other I/O expander chips. Best to use those chips for ordinary switches.

Likewise for Servo library, it only works with normal pins. If you choose a chip for servo motor control, make sure it has a library which really does support servos. And of course make sure that library works with Teensy (open any of its examples and click Verify in Arduino for a first quick sanity check).

Matrix connection of LEDs... probably not. I believe that pushbutton has 3 LEDs in common anode, so maybe you could find a way to connect many of them in a matrix manner. But the description says it has a resistor build inside. Normally with a matrix connection you would not want a resistor on each LED. It's been quite some time since I've used MAX7219, but as I recall it was designed to have only LEDs connected and internally it regulates the current. Whether it would work properly with each LED having a resistor is a good question. My gut feeling (really just gueswork) is it might work but the result might be very dim LED output.

Other people here have done some impressive projects with I/O expanders, so maybe they'll weigh in. But as a general rule, using I/O expanders is almost always a matter of checking carefully whether available software gives the features you need, or writing that sort of software yourself.
Thank you. I did not think about the issues with common anode, however it makes sens that using the MAX7219 would not be ideal.

I think I will try to use the SoftPWM library with the LEDs connected directly to the teensy. Then I would have to perhaps get something like the PCA9685 to control the servos. There are some examples with controllig servos with an arduino using this board.

Another way to 'solve' the issue is to switch to using neopixel (i.e. WS2812B or SK6812) LEDs that are serially programmed. This way you only need one pin to control all of the LEDs, plus another pin for each button (i.e. if you have 4 buttons, you need 5 pins; with the button you list you would need 16 pins). Adafruit sells their rugged buttons with neopixels instead of RGB lights also:

Just a thought: I bet there’s some external chip (SPI or I2C) you could use to drive many LEDs.

Yes, 16-way LED drivers spring to mind, but there are many many LED driver chips out there. Some have programmable PWM, some programmable constant current, some combine these even. They usually just chain together as shift registers.