I know that this issue has been discussed in this forum, but I am a beginner in electronics and I was unable to come up with a solution to my problem by reading the related threads.
I am doing a 3x5 Led matrix (cathodes are connected row-wise):

enter image description here

I used a raspberry Pi B+ with an MCP23017 GPIO expander, 1000 Ohm resistors and 5mm LEDs (20mA, 3.2V). I used 1000 Ohm just because this is what I had. I turn ON one LED at a time (I believe this is called multiplexing). This is my code for displaying the digit 2:

import smbus
import time

bus = smbus.SMBus(1)
bus.write_byte_data(0x20, 0x00, 0x00)#setting GPIOs of bank A as outputs
bus.write_byte_data(0x20, 0x01, 0x00)#setting GPIOs of bank B to outputs

MATRIX = [[1, 1, 1], [0, 0, 1], [1, 1, 1], [1, 0, 0], [1, 1, 1]]

for k in range(100):
   for irow, valr  in enumerate(MATRIX):
       for icol, valc in enumerate(valr):

           A = [0, 0, 0, 0, 0, 0, 0, 0] #the 8 bits to send to bank A of MCP23017
           A[7-icol] = 1 #anode of LED to light up set to HIGH

           B = [1, 1, 1, 1, 1, 1, 1, 1] #the 8 bits to send to bank B of MCP23017
           B[7-irow]=0   #cathode set to LOW

           bus.write_byte_data(DEVICE, 0x12, append(int(''.join(str(e) for e in A), 2))) #bank A

           bus.write_byte_data(DEVICE, 0x13, append(int(''.join(str(e) for e in B), 2))) #bankB


Some LEDs lit despite not being 'told so'. From what I read online, this is due to current leakage. For instance, this is a two:

enter image description here

Where does the problem stem from ? :
- the code?
- The way I drive the LEDs (should I add transistors? (and why?), should I change the value of resistors? should I add pull-up/down resistors?)

I tried alternating between one LED ON then all LEDs OFF (I set all GPIOs to '0') but that didn't solve the problem.


With that expander, it requires 2 I2C bus transactions to change both of the A and B banks. Assuming the I2C is running at 100kHz, each write is going to take at least 26 mS (8 bit address, 8 bits data, 2 ACK bits, start and stop). Add code overhead from running Python, I’m going to guess you’re closer to 50 mS per write.

It looks like you have a 1000 mS loop delay so for approximately 1/20 of the loop time, you’ve changed the A bank but not yet changed the B bank. I’m guessing that the LEDs are producing enough light during the 1/20 to be visible.

Try adding one more write to the loop: turn all of bank B first, before setting the bits on A and then B. This should turn off the LEDs while the A bank is changing.


You are using i2c to communicate with the GPIO expander.

I2C is relatively slow with the result that there will be hundreds of microseconds between the commands to write to device 0x12 and 0x13.

During that time the output of the GPIO expander output at 0x12 will be set to the new data but 0x13 will still be from the the previous data - this can result in unwanted LEDs being lit.

One way to solve this is to write zero to 0x12 to turn off the LEDs, then write 0x13 with new data then write the wanted value to 0x12.

Often when using multiplexed LEDs there can be problems either caused by software delays or just the time that it takes hardware signals to stabilize and will require similar approaches to avoid the problem.


Shouldn't be leakage - the diodes in the 'off' row are reverse-biased. Try checking these things:

  • Make sure you have pull-up disabled

  • Try outputting the rows one at a time, slowly, to see if the sequence is right.

  • \$\begingroup\$ how do I check that pull-up is disabled (pull-up of the MCP23017?). As for outputting the rows, yes I made sure to output one LED at a time and the sequence is correct (actually I turn ON one LED at a time, I mean: for example for the first row of digit 2 that I displayed there, I didn't light up all the 3 LEDs all at the same time, but one LED at a time)) \$\endgroup\$ – S.E.K. Jul 18 '19 at 0:05
  • \$\begingroup\$ The pullup-enable bits are in GPPUA. Make sure they're off. As for the LED sequence doing 3 at a time should be ok. From an I/O perspective, putting all 8 signals on the same GPIO set would be even more efficient. \$\endgroup\$ – hacktastical Jul 18 '19 at 0:13
  • \$\begingroup\$ I set all pullup bit to 0 : bus.write_byte_data(0x20, GPPUA, 0x00), with GPPUA=0x06, but this didn't solve the problem. I did the same thing for GPPUB, but the problem persists. \$\endgroup\$ – S.E.K. Jul 18 '19 at 0:39
  • \$\begingroup\$ Maybe some corruption on your I2C? Try lighting 3 at a time and see if things are different. \$\endgroup\$ – hacktastical Jul 18 '19 at 0:42
  • \$\begingroup\$ Thanks for your prompt responses. I lit up one whole row without problems, then I lit up one whole column without problems, I don't think there's a problem with I2C. \$\endgroup\$ – S.E.K. Jul 18 '19 at 1:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.