Skip to content

Instantly share code, notes, and snippets.

@TheRayTracer
Last active January 12, 2019 08:43
Show Gist options
  • Save TheRayTracer/c915b1ef8bb87b7c854196330ec67542 to your computer and use it in GitHub Desktop.
Save TheRayTracer/c915b1ef8bb87b7c854196330ec67542 to your computer and use it in GitHub Desktop.
This addition helps to drive a MAX7219 chipset for controlling Seven Segement displays and 8x8 led matrices. See the wiring diagram for connection to a Raspberry Pi.
import time
import math
import spidev
import RPi.GPIO as gpio
NO_OP = 0x0
REG_DIGIT0 = 0x1
REG_DIGIT1 = 0x2
REG_DIGIT2 = 0x3
REG_DIGIT3 = 0x4
REG_DIGIT4 = 0x5
REG_DIGIT5 = 0x6
REG_DIGIT6 = 0x7
REG_DIGIT7 = 0x8
REG_DECODEMODE = 0x9
REG_INTENSITY = 0xA
REG_SCANLIMIT = 0xB
REG_SHUTDOWN = 0xC
REG_DISPLAYTEST = 0xF
class MAX7219(object):
MAX_BUFFER_SIZE = 8
def __init__(self, cs):
self.cs = cs
self.buffer = [0] * self.MAX_BUFFER_SIZE
# Setup GPIO.
gpio.setmode(gpio.BCM)
gpio.setup(self.cs, gpio.OUT)
gpio.output(self.cs, gpio.HIGH)
self.__OpenSPI() # Setup SPI.
self.__Setup()
return
def __OpenSPI(self):
self.spi = spidev.SpiDev()
self.spi.open(0, 0)
self.spi.mode = 3
self.spi.max_speed_hz = 1000000
return
def __Setup(self):
self.__WriteCommand(REG_SCANLIMIT, 7)
self.__WriteCommand(REG_DECODEMODE, 0)
self.__WriteCommand(REG_DISPLAYTEST, 0)
self.__WriteCommand(REG_SHUTDOWN, 1)
self.Brightness(1) # Intensity: [0, 15]
self.Clear()
time.sleep(0.1)
return
def __WriteCommand(self, address, data):
gpio.output(self.cs, gpio.LOW)
self.spi.xfer2([address, data])
gpio.output(self.cs, gpio.HIGH)
return
def SetByte(self, index, value):
if index > -1 and index < self.MAX_BUFFER_SIZE:
self.buffer[index] = (value & 0xFF)
return
def RotateLeft(self):
t = self.buffer[self.MAX_BUFFER_SIZE - 1]
for i in xrange(self.MAX_BUFFER_SIZE - 1, 0, -1):
self.buffer[i] = self.buffer[i - 1]
self.buffer[0] = t
return
def RotateRight(self):
t = self.buffer[0]
for i in xrange(0, self.MAX_BUFFER_SIZE - 1, 1):
self.buffer[i] = self.buffer[i + 1]
self.buffer[self.MAX_BUFFER_SIZE - 1] = t
return
def Test(self, mode = False):
t = 0
if mode != False:
t = 1
self.__WriteCommand(REG_DISPLAYTEST, t)
return
def Remove(self):
self.__WriteCommand(REG_SHUTDOWN, 0)
gpio.cleanup()
return
def Clear(self):
self.buffer = [0] * self.MAX_BUFFER_SIZE
self.Flush()
return
def Flush(self):
for i in xrange(0, self.MAX_BUFFER_SIZE, 1):
self.__WriteCommand(REG_DIGIT0 + i, self.buffer[i])
return
def Brightness(self, intensity):
self.__WriteCommand(REG_INTENSITY, intensity)
return
class Matrix8x8(MAX7219):
def __init__(self, cs):
super(Matrix8x8, self).__init__(cs)
return
def SetPixels(self, x, y, state):
if len(x) == len(y) and len(x) == len(state):
for i in xrange(0, len(x), 1):
if state[i] != False:
self.buffer[y[i]] = self.buffer[y[i]] | (0x01 << x[i])
else:
self.buffer[y[i]] = self.buffer[y[i]] & ~(0x01 << x[i])
return
class SevenSegment8(MAX7219):
def __init__(self, cs):
self.DIGITS = [0] * 256
self.DIGITS[ord('-')] = 0x01
self.DIGITS[ord('0')] = 0x7E
self.DIGITS[ord('1')] = 0x30
self.DIGITS[ord('2')] = 0x6D
self.DIGITS[ord('3')] = 0x79
self.DIGITS[ord('4')] = 0x33
self.DIGITS[ord('5')] = 0x5B
self.DIGITS[ord('6')] = 0x5F
self.DIGITS[ord('7')] = 0x70
self.DIGITS[ord('8')] = 0x7F
self.DIGITS[ord('9')] = 0x7B
self.DIGITS[ord('A')] = 0x77
self.DIGITS[ord('a')] = 0x77
self.DIGITS[ord('B')] = 0x1F
self.DIGITS[ord('b')] = 0x1F
self.DIGITS[ord('C')] = 0x4E
self.DIGITS[ord('c')] = 0x4E
self.DIGITS[ord('D')] = 0x3D
self.DIGITS[ord('d')] = 0x3D
self.DIGITS[ord('E')] = 0x4F
self.DIGITS[ord('e')] = 0x4F
self.DIGITS[ord('F')] = 0x47
self.DIGITS[ord('f')] = 0x47
super(SevenSegment8, self).__init__(cs)
return
def PrintHexChar(self, index, char, dp = False):
value = self.DIGITS[ord(char)]
if dp != False:
value = value | 0x80
self.SetByte(index, value)
return
def ClearHexChar(self, index):
self.SetByte(index, 0x00)
return
def PrintHexString(self, strg):
self.Clear()
i = 0
for ch in reversed(strg):
self.PrintHexChar(i, ch, False)
i = i + 1
return
def PrintError(self):
self.Clear()
self.SetByte(7, 0x4F)
self.SetByte(6, 0x05)
self.SetByte(5, 0x05)
self.SetByte(4, 0x1D)
self.SetByte(3, 0x05)
return
def PrintCustomChar(self, index, a, b, c, d, e, f, g, dp):
ch = 0x00
if dp != False:
ch = ch | 0x80
if a != False:
ch = ch | 0x40
if b != False:
ch = ch | 0x20
if c != False:
ch = ch | 0x10
if d != False:
ch = ch | 0x08
if e != False:
ch = ch | 0x04
if f != False:
ch = ch | 0x02
if g != False:
ch = ch | 0x01
self.SetByte(index, ch)
return
def PrintValue(self, value, dp = 0):
dp = min(self.MAX_BUFFER_SIZE, max(dp, 0))
strg = repr(value)
d = strg.find(".")
if dp > 0:
if d < 0:
strg = strg + "."
strg = strg + "00000000"
d = strg.find(".")
end = d + 1 + dp
strg = strg[0:end]
self.Clear()
i = 0
for ch in reversed(strg):
if ch != '.':
self.PrintHexChar(i, ch, dp > 0 and i == dp)
i = i + 1
return
def ProcessBottomRight(dev, x1, y1, x2, y2):
for i in xrange(x1, x2 + 1, 1):
dev.SetPixels([i], [y1], [True])
dev.Flush()
time.sleep(0.25)
for i in xrange(y1 + 1, y2 + 1, 1):
dev.SetPixels([x2], [i], [True])
dev.Flush()
time.sleep(0.25)
if x2 > x1:
ProcessTopLeft(dev, x1, y1 + 1, x2 - 1, y2)
return
def ProcessTopLeft(dev, x1, y1, x2, y2):
for i in xrange(x2, x1 - 1, -1):
dev.SetPixels([i], [y2], [True])
dev.Flush()
time.sleep(0.25)
for i in xrange(y2 - 1, y1 - 1, -1):
dev.SetPixels([x1], [i], [True])
dev.Flush()
time.sleep(0.25)
if x2 > x1:
ProcessBottomRight(dev, x1 + 1, y1, x2, y2 - 1)
return
MAX7219_CS = 23
def TestMatrix8x8():
device = Matrix8x8(MAX7219_CS)
try:
device.Clear()
device.Test(True)
time.sleep(4)
device.Test(False)
ProcessBottomRight(device, 0, 0, 7, 7)
finally:
device.Remove()
return
def TestSevenSegment8():
device = SevenSegment8(MAX7219_CS)
try:
device.Clear()
print("Display error.")
device.PrintError()
device.Flush()
time.sleep(2)
device.Clear()
print("Display characters.")
device.PrintHexChar(0, 'f')
device.PrintHexChar(1, 'e')
device.PrintHexChar(2, 'e')
device.PrintHexChar(3, 'b')
device.PrintHexChar(4, 'd')
device.PrintHexChar(5, 'a')
device.PrintHexChar(6, 'e')
device.PrintHexChar(7, 'd')
device.Flush()
time.sleep(2)
device.Clear()
print("Display floating-point value")
device.PrintValue(math.pi, 7)
device.Flush()
time.sleep(2)
device.Clear()
print("Display negative floating-point value")
device.PrintValue(-.123, 5)
device.Flush()
time.sleep(2)
device.Clear()
print("Display custom characters.")
device.PrintCustomChar(0, False, False, True, True, True, False, True, False)
device.PrintCustomChar(1, True, True, False, False, False, True, True, False)
device.PrintCustomChar(2, False, False, True, True, True, False, True, False)
device.PrintCustomChar(3, True, True, False, False, False, True, True, False)
device.PrintCustomChar(4, False, False, True, True, True, False, True, False)
device.PrintCustomChar(5, True, True, False, False, False, True, True, False)
device.PrintCustomChar(6, False, False, True, True, True, False, True, False)
device.PrintCustomChar(7, True, True, False, False, False, True, True, False)
device.Flush()
time.sleep(2)
device.Clear()
print("Display and rotate string.")
device.PrintHexString("01234567")
device.Flush()
time.sleep(2)
for i in xrange(0, 8, 1):
device.RotateLeft()
device.Flush()
time.sleep(0.5)
finally:
device.Remove()
return
if __name__ == "__main__":
TestSevenSegment8()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment