I am currently trying to build a 3.3v-based 8x7 LED matrix with 2 PCF8574.
The columns are powered by a PCF8574 with an UDN2981, signal pins directly connected
The rows are connected via a PCF8574 and an ULN2003, signal pins connected with 470 ohms pullups.
LEDs are of standard 5mm type with resistors
I2C control is running fine, I am sending random bitmasks or full 0xff to the PCFs.
The weird thing is that I cannot get the LEDs to light up in the matrix, they light up only veeeeerry dimly according to the bitmask. But they light up bright either if I am replacing the ULN2003 with a direct connection to GND, or if I replace the UDN2981 with a direct connection to 3v3.
And of course, the PCF8574/ PCF8575 is not suitable for driving these ICs either.
Attempting to drive a LED matrix from 3.3 V is daring to say the least! The proper matrix driver, the MAX7219, is not specified to 3.3 V. You would do better (FWIW) to use the crude approach with just two 74HC595s.
instead of posting my original schematic, I think it is better to describe what I actually plan:
I am building a control surface for Raspberry Pi with a 8x4 button+led matrix and 8 faders.
The faders are already working over a MCP3008 via SPI.
The matrix consists of 8x4 pushbuttons and 8x4 1.8mm bright LEDs rated at 20mA.
I would have enough GPIO (20) to directly control the matrix without any IO expander or shift register, but I need some transistors because the RPi pins do not support 20ma current output, and consequently the pins for the 4 rows would not be able to cope with the 8x20mA of each LED row.
Do you have any suggestions for alternatives to the ULN/UDN?
As I have pointed out, if you insist on powering it with 3.3 V, then two 74HC595s using 470 Ohm resistors would probably be the most practical way. You are not going to be able to reliably drive the LEDs to 20 mA at 3.3 V. Tough!
OTOH, if you have a Raspberry Pi, you clearly do have 5 V available, so you could best use the proper MAX7219 - the easiest way being to get one of the (used to be) inexpensive partially assembled matrix modules from Aliexpress and wire it to your own array instead of the matrix supplied.
There are also chips that will drive both the LED matrix and the button matrix with which I am less familiar. Just use 5 V where you actually have it.
The MAX7219 has a SPI like interface. It is able to control a matrix of 8x8 = 64 LEDs individually or 8 seven segment digits. You can daisy chain this IC, meaning, with one chip select pin you can control several ICs. The MA7219 is often used for 7 Segment Displays, modules for 8x8 Matrixes are available also.
The HT16K33 has an I2C interface. You can chose from 8 addresses. Each IC can drive 8 x 16 LEDs. There are modules available with 7 Segment LED displays and several Alphanumeric Displays. The HT16K33 can be used to read a key matrix also.
The SX1509 has an I2C interface also. You can chose from 16 addresses. The SX1509 control 16 LEDs. Each LED can have PWM. The SX can "blink" or "pulse" the outputs also. It has an build in keypad controller to read from button matrix.
In my opinion all 3 variants a better usable as LED driver than shift registers.
Indeed, and all three require to operate at 5 V as LED drivers. I have cited the MAX7219, the HT16K33 is also specified at 5 V (4.4 to 5.5 V) and the SX1509 is interesting as while its operating voltage is 3.3 V and not 5 V, it actually requires 5 V as a supply voltage for the LEDs (it would probably work OK at somewhat less, but not really well at 3.3 V) and only drives 16 LEDs per chip so not useful for driving a matrix - you would need seven of them to drive your 56 LEDs.
But as you evidently do have 5 V available, you should be able to work from here. The HT16K33 would also scan your key matrix.