To connections between the matrix and the Pi are really simple, you just need to connect 4 signals directly together : GND, 3V3, DATA and CLK. There is no need for pull-up resistor on the i2c clock and data lines, I presume the Pi already have them. The display is designed for 5V but it works really well at 3.3V.
For using i2c on the Raspberry Pi, you need to make some little configurations and install the Python libraries. These steps are outlined on this Instructable tutorial.
You will also need the PyQt4 package, install it with:
sudo apt-get install python-qt4
The final Python script is listed below. The LedMatrix class is the i2c communication part of my program and MatrixWidget is the graphical user interface. The Qt windows part does essentially two things, it reacts to mouse press and draw an array of ellipse (the virtual LEDs).
If you have any questions with the code, just ask in the comments and I will be glad to help. Happy coding!
#!/usr/bin/env python
import sys
from smbus import SMBus
from PyQt4 import QtGui, QtCore
class LedMatrix():
ADDRESS = 0x70
OSCILLATOR_ON = 0x21
BLINK_CMD = 0x80
DISPLAY_ON = 0x01
BLINK_2HZ = 0x01
BLINK_1HZ = 0x02
BLINK_HALFHZ = 0x03
BRIGHTNESS_CMD = 0xE0
POS_X = (128, 1, 2, 4, 8, 16, 32, 64)
POSn_X = (127, 254, 253, 251, 247, 239, 223, 191)
POS_Y = (7, 0, 1, 2, 3, 4, 5, 6)
def __init__(self, blink=0, brightness=15):
self.bus = SMBus(1) #device on i2c channel 1
self.bus.write_byte(self.ADDRESS, self.OSCILLATOR_ON)
self.bus.write_byte(self.ADDRESS, self.BLINK_CMD|self.DISPLAY_ON|(blink<<1))
self.bus.write_byte(self.ADDRESS, self.BRIGHTNESS_CMD|brightness)
self.clearBuffer()
def setBrightness(self, brightness):
self.bus.write_byte(self.ADDRESS, self.BRIGHTNESS_CMD|brightness)
def setBlinkRate(self, blink):
self.bus.write_byte(self.ADDRESS, self.BLINK_CMD|self.DISPLAY_ON|(blink<<1))
def setPixel(self, x, y, state):
if state:
self.buffer[self.POS_Y[y]]|=self.POS_X[x]
else:
self.buffer[self.POS_Y[y]]&=self.POSn_X[x]
def clearBuffer(self):
self.buffer = [0]*8
def writeBuffer(self):
data = []
for row in self.buffer:
data.append(0)
data.append(row)
self.bus.write_block_data(self.ADDRESS, 0x00, data)
class MatrixWidget(QtGui.QWidget):
def __init__(self):
super(MatrixWidget, self).__init__()
self.w=20
self.setGeometry(300, 300, self.w*10, self.w*10)
self.setWindowTitle('Led Matrix')
self.clearPixelBuffer()
self.setFixedSize(self.width(),self.height())
self.leds = LedMatrix()
self.show()
def clearPixelBuffer(self):
self.buffer = [[0 for _ in range(8)] for _ in range(8)]
def mousePressEvent(self, QMouseEvent):
x = QMouseEvent.pos().x()
y = QMouseEvent.pos().y()
x = x/self.w-1
y = y/self.w-1
if x==-1 or y==-1 or x==8 or y==8:
self.clearPixelBuffer()
self.update()
self.leds.clearBuffer()
self.leds.writeBuffer()
return
pixel = self.buffer[x][y]
if pixel:
self.leds.setPixel(x, y, False)
self.buffer[x][y]=0
else:
self.leds.setPixel(x, y, True)
self.buffer[x][y]=1
self.update()
self.leds.writeBuffer()
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
self.refresh(qp, e)
qp.end()
def drawLed(self, qp, x, y):
state = self.buffer[x][y]
if state:
col = QtGui.QColor("#FFF71C") #bright yellow
else:
col = QtGui.QColor("#373511") #dark yellow
qp.setPen(col)
qp.setBrush(col)
qp.drawEllipse(self.w+self.w*x,self.w+self.w*y,self.w-3,self.w-3)
def refresh(self, qp, event):
qp.setBrush(QtCore.Qt.black)
qp.drawRect(event.rect())
for y in range(8):
for x in range(8):
self.drawLed(qp, x, y)
if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
ex = MatrixWidget()
sys.exit(app.exec_())