MCP23017 wiring schematic.

DisplayBug is driven over I2C using a 16-bit GPIO expander, which makes it easy to interface to MCU's without many pins, like ESP, and boards like Raspberry Pi etc.

Currently I'm using Python, but the refresh rates arent high enough and it flickers. I can solve this by driving the I2C (Actually SMBus for compatibility) faster with C++.

# Setup I2C
>>import smbus,thread
>>from time import sleep
>>bus = smbus.SMBus(1)
>>addr = 0x27

# Initialise
>>bus.write_byte_data(addr,0,0)
>>bus.write_byte_data(addr,1,0)

# Write to display
>>bus.write_byte_data(addr,0x01,255)
>>bus.write_byte_data(addr,0x15,byte1)
>>bus.write_byte_data(addr,0x14,byte2)
>>bus.write_byte_data(addr,0x01,mask)

Writing to the display is complicated. Because the even columns have their anodes on bits 1-5 and cathodes on bits 6-16, and the odd columns are inverted, simply switching bits 1-5 on with bits 6-16 on does not light the correct LEDs. You have to mask out the rows you dont want displayed by setting bits 2-5 as inputs, which are high impedance so power does not flow into them and the rest of the LEDs stay off.

Then, do the next line by setting 1,3,4,5 as inputs and so on.

It runs as a thread, pulling data from a buffer.

def display_thread():
  global buffr,bitpos
  print 'Started...'
  mask=1; line=0
  while running:
    lbyte1=buffr[line][0]
    lbyte2=buffr[line][1]
    rbyte1=255-buffr[line][2]
    rbyte2=255-buffr[line][3]
    display(lbyte1,lbyte2,mask^31)
    sleep(0.0025)
    display(rbyte1,rbyte2,mask^31)
    sleep(0.0025)
    mask=mask*2
    line=line+1
    if mask>16:
      mask=1
      line=0
  print 'display_thread() terminated...'