Need help-- so many options for multiplexing!

Hello all, this is my first post to this forum and I spent several hours researching so I'm hoping I haven't missed a thread on the same topic somewhere (apologies in advance if so). I'm in need of a scalable solution for multiplexing/demuxing using an Arduino Uno that doesn't utilize I2C (long story, but the I2C bus on my Uno is otherwise occupied and I can't have LED drivers taking up I2C addresses on my network). Because of my application, I need to stick with the Uno CPU so I can't take advantage of boards like the Mega which would provide native ports.

I've found a number of threads on port expansion, reading sensors, driving outputs, etc. All very helpful. I think I've settled on a solution for multiplexing the input of multiple sensors (using 4051's-- this seems to be the easier part). I'm having trouble settling on the right solution for my outputs.

Here's the scenario. I need to be able to expand the number of output ports on my Uno so I can control up to 16 LEDs or other devices (~ 200ma mini relays). No high-current LEDs needed here (total anticipated current draw on any one output would be 200ma or less), but I want the flexibility of using the outputs to drive individual LEDs (or strings of up to 10x 20ma LEDs on a single output) or to drive relays (small relays, not mains-type relays). I'd also like to have PWM available for the LEDs (though that's not a hard requirement).

I found with the analog multiplexers (4051) that the outputs assigned were only momentary (also found that in this forum, sadly after hours of hitting my head against the wall)-- I need a solution where the Arduino can "set it and forget it" for each of 16 ports. I found the I2C LED drivers which look great, except that they take up I2C addresses (which I need to preserve for my application).

Sorry for the long story, but I want to set the stage. I'm thinking I would be all set if I could find a 16-port driver that would power my LEDs and also my relays. Because of the ~200ma current needs for both, I was also thinking of using a darlington array to drive the LEDs and relays from a separate 5v supply.

Thoughts? Any recommendations for 16 ports of latched output with optional PWM that could be used (through darlington arrays?) to drive ~200ma of LEDs or a small relay on each port?

Thank you in advance for any guidance you can provide!


Typically shift registers are used for this. The 74595 is common but it can't drive high currents so needs external components (like a ULN2308 driver chip) if you want to control relays etc.

Chips like the TLC5927 and TLC5916 do the same but have all the circuitry need to drive LEDs directly.

Theoretically PWM can be done through a shift reg but it would be a bit of work.

Chips like the MAX7219 can MUX a lot of LEDs and do brightness control as well. While the TLC5940 is probably just right for this as it has PWM built in.


Thanks for the information, Rob! I did some additional research today and determined that the TLC5940 as you say is probably best suited for my needs. Those look like pretty flexible, powerful devices. I ordered a few and hope to have them in a few days.

Looks like the chips can drive up to 120ma per output, so I also picked up some 10ma 5v relays-- I'm hoping I can just attach these directly to the output pins of the TLC5940 without the need for darlingtons or mosfets. I also have some darlington arrays which I'll test with the LED outputs when I need to drive more than 120ma of LED on a single pin.

Thanks again!


120ma per output

Not for all pins at once I wouldn't think. The total package heat dissipation has to be considered. But it looks like what you plan to drive won't over tax the chip.


I’m hoping I can just attach these directly to the output pins of the TLC5940 without the need for darlingtons or mosfets

The TLC5940 is a PWM controller for LEDs. It is not really suitable for driving a relay. It also needs constant feeding with pulses so is a bit heavy on the CPU time. I would recommend the 23S17 This uses SPI in place of I2C and is fast, it gives 16 I/O lines, I used it on this project Proxxon MF70 Miller CNC CONVERSION and a few others. You can string 8 of them on the same SPI bus. Only 30mA each output but then you will not get much more and it is a set and forget interface.

the I2C bus on my Uno is otherwise occupied and I can’t have LED drivers taking up I2C addresses on my network

With 128 addresses available it is odd that you can’t spare one. There are switching tricks you can do to extend the range of bus addresses as well.

Thanks for the additional information, Mike. The 23S17 definitely looks interesting-- I will check it out. Though I am concerned about the number of additional pins required for SPI communication (I’m fairly maxed out on pins as it is with my design). I do like the “set it and forget it” though. Let me ask the reverse question, then: if I don’t need PWM for my LEDs, could I use a 23S17 to drive them instead of the TLC5940?

On the topic of I2C addressing, it isn’t that I have 128 devices on my bus and can’t spare an address. It’s more that the I2C devices I’ve seen like the 23017 don’t allow for fully configurable addressing. The 23017 has the first three (of seven) of its address bytes hard-coded to 0100-- in reality this leaves just three remaining address bits (or only eight 23017 devices on an I2C bus). If my design calls for 23017’s to be associated with every microcontroller on my network, that limits the number of microcontroller drvices on my I2C bus to the number of addressable 23017’s (or eight vs. 128). That’s an unacceptable reduction in number of devices. Ideally, the associated I2C devices within each microcontroller-managed device on my bus would have the full seven address bits settable-- that way I could easily set up a scheme like “Microcontroller has I2C address and I/O expander has I2C address <x+1>” but unless I’m missing something, that isn’t possible with most I2C companion devices (like the 23017, or I2C RAM, etc.)-- most of these seem to have some/most of their address bits hardwired.

If there were I2C companion devices with all seven of their I2C address bytes settable, that would be ideal.


OK now that I've had my daily dose of caffeine it just occurred to me that the TLC5940 interfaces to the Arduino via SPI, so I was already planning to commit those pins to SPI communication for that driver chip. My question (and this is my ignorance of SPI): can I have both a TLC5940 and a 23S17 on the same SPI bus? Anything special I need to do to enable that? Does anyone have a schematic?

OK I guess that was more than a single question. I'll shut up now and wait for an answer. :blush:

Thank you!


YES, SPI can SHARE data pins with other devices,... it is a BUS interface. You only need to have different SLAVE SELECT pins for each device.

While I would agree with that in theory, when you use the TLC5940 you are actually feeding it with high speed clocks from those pins. This in effect stops you using it with other devices. However, it is just as easy to bit bang an SPI interface on any pins, something I have done on a few of my projects.

in reality this leaves just three remaining address

No not really, I don't understand why you think this.

If my design calls for 23017's to be associated with every microcontroller on my network,

This statement is odd. If you have a micro controller then is that not a separate I2C bus on each controller? On the other hand if your microcontroller is acting as an I2C slave then you can have a fully definable 7 bit address.

By switching the I2C bus you can have as many devices at the same address as you want on the same I2C bus.

Thanks Mike, I'll elaborate a bit on my comments earlier. According to p.8 of the datasheet for the 23017, "The MCP23017 is a slave I2C interface device that supports 7-bit slave addressing, with the read/write bit filling out the control byte. The slave address contains four fixed bits and three user-defined hardware address bits (pins A2, A1 and A0)." Hence my comment that, while the devices theoretically support the full 7-bit address space of I2C, in reality only thee of the 7 address bits are user-settable, meaning only 12 devices can exist (with unique addresses) on a single I2C bus (addresses 0100000-0100111). Unless I'm reading this wrong?

Your comment about it being ok to have slave devices with duplicate addresses on a single I2C bus is interesting-- I hadn't read that anywhere and wonder what the impact would be in my scenario (one master and many slaves on a single bus-- each slave being its own standalone Arduino setup and each slave, theoretically, needing a port expander like the 23017). If each slave (which would have its own unique address on the bus) had a companion 23017 (also on the same bus as the master and all the other slaves) that had the same address as all the other 23017's (or one of the 12 possible user-settable addresses per the 23017 specs and 4 hard-coded I2C address bits), would that really work? Would each slave (standalone Arduino) be able to independently manage its attached 23017, or would a command issued to any 23017 on the bus cause all of them to respond?