Last active
January 12, 2019 08:43
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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