8x8 matrix sample python code

by cameraready on Tue Mar 26, 2013 9:38 pm

I just got my 8x8 matrix assembled tonight and I'm testing it on my Rpi. If I'm reading the Adafruit_8x8.py code correctly there are two main methods to write to the display.

setPixel(x, y) and writeRowRaw(<row>, <values>)

Anyone have other examples for Python?

Here's part of what I came up with so far.

Code: Select all
grid = EightByEight(address=0x70)

smile_bmp = [0b00011110,0b00100001,0b11010010,0b11000000,0b11010010,0b11001100,0b00100001,0b00011110]
neutral_bmp = [0b00011110,0b00100001,0b11010010,0b11000000,0b11011110,0b11000000,0b00100001,0b00011110]
frown_bmp = [0b00011110,0b00100001,0b11010010,0b11000000,0b11001100,0b11010010,0b00100001,0b00011110]


Code: Select all

# Write a smiley face
  for i in range(0,8):
    grid.writeRowRaw(i, smile_bmp[i])
  time.sleep(.33)
 
  # Write a neutral face
  for i in range(0,8):
    grid.writeRowRaw(i, neutral_bmp[i])
  time.sleep(.33)
   
  # Write a frown face
  for i in range(0,8):
    grid.writeRowRaw(i, frown_bmp[i])
  time.sleep(.33)


I'm also using the 7 segment display but that seems a bit easier to program.
Attachments
20130326_215857-1.jpg
Rpi Smiles
20130326_215857-1.jpg (75.4 KiB) Viewed 1067 times
cameraready
 
Posts: 34
Joined: Wed Jan 30, 2013 10:10 pm

Re: 8x8 matrix sample python code

by adafruit_support_mike on Wed Mar 27, 2013 2:18 pm

Looks good!
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 7015
Joined: Thu Feb 11, 2010 1:51 pm

Re: 8x8 matrix sample python code

by cameraready on Thu Mar 28, 2013 10:34 pm

I tried to call the setBrightness() function from my sample code and was getting an error that it wasn't a valid attribute.

AttributeError: EightByEight instance has no attribute 'setBrightness'


I checked the Adafruit_8x8.py code and noticed that it didn't reference it there. It is listed in the Adafruit_LEDBackpack.py code so I added this method to my Adafruit_8x8.py that references the same method in the backpack code.

Code: Select all
  def setBrightness(self, brightness):
    "Sets the brightness level from 0..15"
    self.disp.setBrightness(brightness)


Here's a couple loops I used to go through all the brightness settings.

Code: Select all
  # Loop through brightness settings
  for i in range(0,15):
    grid.setBrightness(i)
    time.sleep(.1)
   
  for i in range(0,15):
    grid.setBrightness(15-i)
    time.sleep(.1)


I'm not sure if this was the correct way to add the method but it seems to work. :)
cameraready
 
Posts: 34
Joined: Wed Jan 30, 2013 10:10 pm

Re: 8x8 matrix sample python code

by adafruit_support_mike on Fri Mar 29, 2013 6:52 pm

The code looks good to me. Congratulations, you've just hacked your first library! ;-)
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 7015
Joined: Thu Feb 11, 2010 1:51 pm

Re: 8x8 matrix sample python code

by cameraready on Tue Apr 09, 2013 9:24 pm

I played around with this code and have the design scrolling on the matrix. I had to add the getBuffer() method from the LEDBackpack code. I ordered the Programming the Raspberry Pi book this week so I should have that as a reference for more code.

Needed for the getBuffer() method in Adafruit_8x8.py

Code: Select all
def getBuffer(self):
    return self.disp.getBuffer()


New methods for test displays. The dispRandGrid() turns on random leds in the grid and the dispRotate() displays the smiley face and shifts it to the right. The dispRevRotate() shifts everything to the left. Ultimately I want to get the code to display text and have it scroll.

Code: Select all
def dispSmile():
    # Write a smiley face
    for i in range(0,8):
        grid.writeRowRaw(i, smile_bmp[i])

def dispRandGrid():
    # diplay random dots on the 8x8 grid
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    time.sleep(.02)
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    time.sleep(.02)
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    time.sleep(.02)
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    time.sleep(.02)
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    time.sleep(.02)
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    time.sleep(.02)
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    time.sleep(.02)
    grid.setPixel(random.randint(0,7),random.randint(0,7))
    #print grid.getBuffer()
   
def dispRotate():
    dispSmile()
   
    for x in range(0,8):
        buffer = grid.getBuffer()
        newBytes = []
   
        for y in range(0,8):
            i = ((y+1)%8)
            newBytes.append(buffer[i])
       
        # Use sleep here to control scrolling speed
        time.sleep(.05)
   
        for z in range(0,8):
            j = z
            grid.writeRowRaw(z, newBytes[j])
       
def dispRevRotate():
    dispSmile()
   
    for x in range(0,8):
        buffer = grid.getBuffer()
        newBytes = []
   
        for y in range(8,0,-1):
            i = (y-2)%8
            newBytes.append(buffer[i])
       
        # Use sleep here to control scrolling speed
        time.sleep(.05)
   
        for z in range(0,8):
            # 7-<num> used to reverse direction
            j = 7-z
            grid.writeRowRaw(z, newBytes[j])

while True:
## UNCOMMENT THE METHOD TO USE ##
        #grid.clear()
        #dispRandGrid()
        #dispRotate()
        dispRevRotate()


The random numbers require
Code: Select all
import random
random.seed()
cameraready
 
Posts: 34
Joined: Wed Jan 30, 2013 10:10 pm

Re: 8x8 matrix sample python code

by cameraready on Thu Jun 06, 2013 9:33 pm

I finally got back to working on this code and almost have it working. The only issue I have is that it's wrapping the characters around the screen. I've checked my loops and wrap variable and can't figure it out.

I still need to finish porting the Adafruit_GFX library but most of the methods I'm using are complete. Once I get this sorted out I'll finish the rest of the methods and test them. Plus I need to get a level shifter so that I can add more matrices to my Pi. :wink:

If anyone sees where I made a mistake in this code let me know.

Thanks!

Partial Adafruit_GFX.py library
Code: Select all
#!/usr/bin/python

#/******************************************************************
# This is the core graphics library for all our displays, providing
# basic graphics primitives (points, lines, circles, etc.). It needs
# to be paired with a hardware-specific library for each display
# device we carry (handling the lower-level functions).
# Adafruit invests time and resources providing this open
# source code, please support Adafruit and open-source hardware
# by purchasing products from Adafruit!
# Written by Limor Fried/Ladyada for Adafruit Industries.
# BSD license, check license.txt for more information.
# All text above must be included in any redistribution.
#
# Port of library from the C++ for Arduino
# 6/6/2013
#******************************************************************/

from glcdfont import glcdfont


class Adafruit_GFX(object):

    def __init__(self, w, h):
        self.WIDTH = w
        self.HEIGHT = h
        self._width = w
        self._height = h

        self.rotation = 0
        self.cursor_x = 0
        self.cursor_y = 0
       
        self.textsize = 1
        self.textcolor = 0xFFFF
        self.textbgcolor = 0xFFFF
       
        self.wrap = True
        self.font = glcdfont().getfont()
   
    #  this must be defined by the subclass
    def drawPixel(self, x, y, color):
        pass
   
    def invertDisplay(self, i):
        pass

    # these are 'generic' drawing functions, so we can share them!
    #def drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color):
    #def drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color):
    #def drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color):
    #def drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color):
    #def fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color):
    #def fillScreen(uint16_t color):

    #def drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color):
    #def drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color):
    #def fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color):
    #def fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color):

    #def drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color):
    #def fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color):
    #def drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color):
    #def fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color):

    #def drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color):
   
    def write(self, c):
        if (c == '\n'):
            self.cursor_y += textsize*8
            self.cursor_x = 0
        elif (c == '\r'):
            pass # skip em
        else:
            self.drawChar(self.cursor_x, self.cursor_y, c, self.textcolor, self.textbgcolor, self.textsize)
            self.cursor_x += self.textsize*6
            if (self.wrap and (self.cursor_x > (self._width - self.textsize*6))):
                self.cursor_y += self.textsize*8
                self.cursor_x = 0

    # self.draw a character
    def drawChar(self, x, y, c, color, bg, size):
        if ((x >= self._width)            or  # Clip right \
            (y >= self._height)           or  # Clip bottom
            ((x + 5 * size - 1) < 0)      or  # Clip left
            ((y + 8 * size - 1) < 0)):        # Clip top
            return

        for i in range(0,6): #(i=0; i<6; i+=1)
            if (i == 5):
                line = 0x0
            else:
                line = self.font[(ord(c)*5)+i] #pgm_read_byte(font+(c*5)+i)
            for j in range(0,8): #(j = 0; j<8; j+=1)
                if (line & 0x1):
                    if (size == 1): # default size
                        self.drawPixel(x+i, y+j, color)
                    else:           # big size
                       fillRect(x+(i*size), y+(j*size), size, size, color)
                elif (bg != color):
                    if (size == 1): # default size
                        self.drawPixel(x+i, y+j, bg)
                    else:           # big size
                        fillRect(x+i*size, y+j*size, size, size, bg)
                #print('ord(c): ' + str(ord(c)) + ' line: ' + str(bin(line)))
                line >>= 1

    def setCursor(self, x, y):
        self.cursor_x = x
        self.cursor_y = y

    def getCursor(self):
        return ('' + str(self.cursor_x) + ',' + str(self.cursor_y))

    def setTextSize(self, s):
        if s > 0:
            self.textsize = s
        else:
            self.textsize = 1           

    def setTextColor(self, c):
        self.textcolor = c
        self.textbgcolor = c
        # for 'transparent' background, we'll set the bg
        # to the same as fg instead of using a flag

    def setTextColor(self, c, b=None):
        self.textcolor = c
        self.textbgcolor = b

    def setTextWrap(self, w):
        self.wrap = w

    def getRotation(self):
        self.rotation %= 4
        return self.rotation

    def setRotation(self, x):
        x %= 4    # cant be higher than 3
        self.rotation = x
        if x == 0 or x == 2:
            self._width = self.WIDTH
            self._height = self.HEIGHT
        elif x == 1 or x == 3:
            self._width = self.HEIGHT
            self._height = self.WIDTH
        else:
            return

    # return the size of the display which depends on the rotation!
    def width(self):
        return self._width

    def height(self):
        return self._height


Slightly modified Adafruit_LEDBackpack.py
Code: Select all
#!/usr/bin/python

from copy import copy
from Adafruit_I2C import Adafruit_I2C
from Adafruit_GFX import Adafruit_GFX

# ============================================================================
# LEDBackpack Class
# ============================================================================

class LEDBackpack(Adafruit_GFX):
  i2c = None

  # Registers
  __HT16K33_REGISTER_DISPLAY_SETUP        = 0x80
  __HT16K33_REGISTER_SYSTEM_SETUP         = 0x20
  __HT16K33_REGISTER_DIMMING              = 0xE0

  # Blink rate
  __HT16K33_BLINKRATE_OFF                 = 0x00
  __HT16K33_BLINKRATE_2HZ                 = 0x01
  __HT16K33_BLINKRATE_1HZ                 = 0x02
  __HT16K33_BLINKRATE_HALFHZ              = 0x03

  # Display buffer (8x16-bits)
  __buffer = [0x0000, 0x0000, 0x0000, 0x0000, \
              0x0000, 0x0000, 0x0000, 0x0000 ]

  # Constructor
  def __init__(self, w, h, address=0x70, debug=False):
    Adafruit_GFX.__init__(self, w, h)
    self.i2c = Adafruit_I2C(address)
    self.address = address
    self.debug = debug

    # Turn the oscillator on
    self.i2c.write8(self.__HT16K33_REGISTER_SYSTEM_SETUP | 0x01, 0x00)

    # Turn blink off
    self.setBlinkRate(self.__HT16K33_BLINKRATE_OFF)

    # Set maximum brightness
    self.setBrightness(15)

    # Clear the screen
    self.clear()

  def setBrightness(self, brightness):
    "Sets the brightness level from 0..15"
    if (brightness > 15):
      brightness = 15
    self.i2c.write8(self.__HT16K33_REGISTER_DIMMING | brightness, 0x00)

  def setBlinkRate(self, blinkRate):
    "Sets the blink rate"
    if (blinkRate > self.__HT16K33_BLINKRATE_HALFHZ):
       blinkRate = self.__HT16K33_BLINKRATE_OFF
    self.i2c.write8(self.__HT16K33_REGISTER_DISPLAY_SETUP | 0x01 | (blinkRate << 1), 0x00)

  def setBufferRow(self, row, value, update=True):
    "Updates a single 16-bit entry in the 8*16-bit buffer"
    if (row > 7):
      return                    # Prevent buffer overflow
    self.__buffer[row] = value  # value # & 0xFFFF
    if (update):
      self.writeDisplay()       # Update the display

  def getBuffer(self):
    "Returns a copy of the raw buffer contents"
    bufferCopy = copy(self.__buffer)
    return bufferCopy
 
  def writeDisplay(self):
    "Updates the display memory"
    bytes = []
    for item in self.__buffer:
      bytes.append(item & 0xFF)
      bytes.append((item >> 8) & 0xFF)
    self.i2c.writeList(0x00, bytes)

  def clear(self, update=True):
    "Clears the display memory"
    self.__buffer = [ 0, 0, 0, 0, 0, 0, 0, 0 ]
    if (update):
      self.writeDisplay()

led = LEDBackpack(8,8,0x70)



Modified Adafruit_8x8.py
Code: Select all
#!/usr/bin/python

from Adafruit_LEDBackpack import LEDBackpack

# ===========================================================================
# 8x8 Pixel Display
# ===========================================================================

class EightByEight(LEDBackpack):
  #disp = None
  rotation = None

  # Constructor
  def __init__(self, address=0x70, debug=False):
    if (debug):
      print "Initializing a new instance of LEDBackpack at 0x%02X" % address
    LEDBackpack.__init__(self, 8, 8, address, debug)
    self.rotation = 0

  def writeRowRaw(self, charNumber, value):
    #"Sets a row of pixels using a raw 16-bit value"
    if (charNumber > 7):
      return
    # Set the appropriate row
    self.setBufferRow(charNumber, value)

  def clearPixel(self, x, y):
    #"A wrapper function to clear pixels (purely cosmetic)"
    self.setPixel(x, y, 0)

  def drawPixel(self, x, y, color=1):
    # Added rotation code 4/16/13 - RH
    if self.rotation == 1:
      x, y = self.swap(x, y)
      x = 8 - x - 1
    elif self.rotation == 2:
      x = 8 - x - 1
      y = 8 - y - 1
    elif self.rotation == 3:
      x, y = self.swap(x, y)
      y = 8 - y - 1
     
    #"Sets a single pixel"
    if (x >= 8):
      return
    if (y >= 8):
      return   
    x += 7   # ATTN: This might be a bug?  On the color matrix, this causes x=0 to draw on the last line instead of the first.
    x %= 8
    # Set the appropriate pixel
    buffer = self.getBuffer()
    if (color):
      self.setBufferRow(y, buffer[y] | 1 << x)
    else:
      self.setBufferRow(y, buffer[y] & ~(1 << x))
     
  # Used to rotate display 4/16/13 - RH
  # Corrected for dual output 6/5/13 - RH
  def swap(self, x, y):
      temp = x
      x = y
      y = temp
      return (x, y)

  # Added 6/3/13 - RH   
  def printMessage(self, text):
      for letter in range(0, len(text)):
        self.write(text[letter])
        if (self.debug):
            print(text[letter])

class ColorEightByEight(EightByEight):
  def setPixel(self, x, y, color=1):
    #"Sets a single pixel"
    if (x >= 8):
      return
    if (y >= 8):
      return

    x %= 8

    # Set the appropriate pixel
    buffer = self.disp.getBuffer()

    # TODO : Named color constants?
    # ATNN : This code was mostly taken from the arduino code, but with the addition of clearing the other bit when setting red or green.
    #        The arduino code does not do that, and might have the bug where if you draw red or green, then the other color, it actually draws yellow.
    #        The bug doesn't show up in the examples because it's always clearing.

    if (color == 1):
      self.disp.setBufferRow(y, (buffer[y] | (1 << x)) & ~(1 << (x+8)) )
    elif (color == 2):
      self.disp.setBufferRow(y, (buffer[y] | 1 << (x+8)) & ~(1 << x) )
    elif (color == 3):
      self.disp.setBufferRow(y, buffer[y] | (1 << (x+8)) | (1 << x) )
    else:
      self.disp.setBufferRow(y, buffer[y] & ~(1 << x) & ~(1 << (x+8)) )


5x7 font glcdfont.py
Code: Select all
#!/usr/bin/python

#standard ascii 5x7 font
class glcdfont(object):

    def __init__(self):
        self.font = [ \
            0x00, 0x00, 0x00, 0x00, 0x00,   
            0x3E, 0x5B, 0x4F, 0x5B, 0x3E,     
            0x3E, 0x6B, 0x4F, 0x6B, 0x3E,    
            0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
            0x18, 0x3C, 0x7E, 0x3C, 0x18,
            0x1C, 0x57, 0x7D, 0x57, 0x1C,
            0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
            0x00, 0x18, 0x3C, 0x18, 0x00,
            0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
            0x00, 0x18, 0x24, 0x18, 0x00,
            0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
            0x30, 0x48, 0x3A, 0x06, 0x0E,
            0x26, 0x29, 0x79, 0x29, 0x26,
            0x40, 0x7F, 0x05, 0x05, 0x07,
            0x40, 0x7F, 0x05, 0x25, 0x3F,
            0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
            0x7F, 0x3E, 0x1C, 0x1C, 0x08,
            0x08, 0x1C, 0x1C, 0x3E, 0x7F,
            0x14, 0x22, 0x7F, 0x22, 0x14,
            0x5F, 0x5F, 0x00, 0x5F, 0x5F,
            0x06, 0x09, 0x7F, 0x01, 0x7F,
            0x00, 0x66, 0x89, 0x95, 0x6A,
            0x60, 0x60, 0x60, 0x60, 0x60,
            0x94, 0xA2, 0xFF, 0xA2, 0x94,
            0x08, 0x04, 0x7E, 0x04, 0x08,
            0x10, 0x20, 0x7E, 0x20, 0x10,
            0x08, 0x08, 0x2A, 0x1C, 0x08,
            0x08, 0x1C, 0x2A, 0x08, 0x08,
            0x1E, 0x10, 0x10, 0x10, 0x10,
            0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
            0x30, 0x38, 0x3E, 0x38, 0x30,
            0x06, 0x0E, 0x3E, 0x0E, 0x06,
            0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x5F, 0x00, 0x00,
            0x00, 0x07, 0x00, 0x07, 0x00,
            0x14, 0x7F, 0x14, 0x7F, 0x14,
            0x24, 0x2A, 0x7F, 0x2A, 0x12,
            0x23, 0x13, 0x08, 0x64, 0x62,
            0x36, 0x49, 0x56, 0x20, 0x50,
            0x00, 0x08, 0x07, 0x03, 0x00,
            0x00, 0x1C, 0x22, 0x41, 0x00,
            0x00, 0x41, 0x22, 0x1C, 0x00,
            0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
            0x08, 0x08, 0x3E, 0x08, 0x08,
            0x00, 0x80, 0x70, 0x30, 0x00,
            0x08, 0x08, 0x08, 0x08, 0x08,
            0x00, 0x00, 0x60, 0x60, 0x00,
            0x20, 0x10, 0x08, 0x04, 0x02,
            0x3E, 0x51, 0x49, 0x45, 0x3E,
            0x00, 0x42, 0x7F, 0x40, 0x00,
            0x72, 0x49, 0x49, 0x49, 0x46,
            0x21, 0x41, 0x49, 0x4D, 0x33,
            0x18, 0x14, 0x12, 0x7F, 0x10,
            0x27, 0x45, 0x45, 0x45, 0x39,
            0x3C, 0x4A, 0x49, 0x49, 0x31,
            0x41, 0x21, 0x11, 0x09, 0x07,
            0x36, 0x49, 0x49, 0x49, 0x36,
            0x46, 0x49, 0x49, 0x29, 0x1E,
            0x00, 0x00, 0x14, 0x00, 0x00,
            0x00, 0x40, 0x34, 0x00, 0x00,
            0x00, 0x08, 0x14, 0x22, 0x41,
            0x14, 0x14, 0x14, 0x14, 0x14,
            0x00, 0x41, 0x22, 0x14, 0x08,
            0x02, 0x01, 0x59, 0x09, 0x06,
            0x3E, 0x41, 0x5D, 0x59, 0x4E,
            0x7C, 0x12, 0x11, 0x12, 0x7C,
            0x7F, 0x49, 0x49, 0x49, 0x36,
            0x3E, 0x41, 0x41, 0x41, 0x22,
            0x7F, 0x41, 0x41, 0x41, 0x3E,
            0x7F, 0x49, 0x49, 0x49, 0x41,
            0x7F, 0x09, 0x09, 0x09, 0x01,
            0x3E, 0x41, 0x41, 0x51, 0x73,
            0x7F, 0x08, 0x08, 0x08, 0x7F,
            0x00, 0x41, 0x7F, 0x41, 0x00,
            0x20, 0x40, 0x41, 0x3F, 0x01,
            0x7F, 0x08, 0x14, 0x22, 0x41,
            0x7F, 0x40, 0x40, 0x40, 0x40,
            0x7F, 0x02, 0x1C, 0x02, 0x7F,
            0x7F, 0x04, 0x08, 0x10, 0x7F,
            0x3E, 0x41, 0x41, 0x41, 0x3E,
            0x7F, 0x09, 0x09, 0x09, 0x06,
            0x3E, 0x41, 0x51, 0x21, 0x5E,
            0x7F, 0x09, 0x19, 0x29, 0x46,
            0x26, 0x49, 0x49, 0x49, 0x32,
            0x03, 0x01, 0x7F, 0x01, 0x03,
            0x3F, 0x40, 0x40, 0x40, 0x3F,
            0x1F, 0x20, 0x40, 0x20, 0x1F,
            0x3F, 0x40, 0x38, 0x40, 0x3F,
            0x63, 0x14, 0x08, 0x14, 0x63,
            0x03, 0x04, 0x78, 0x04, 0x03,
            0x61, 0x59, 0x49, 0x4D, 0x43,
            0x00, 0x7F, 0x41, 0x41, 0x41,
            0x02, 0x04, 0x08, 0x10, 0x20,
            0x00, 0x41, 0x41, 0x41, 0x7F,
            0x04, 0x02, 0x01, 0x02, 0x04,
            0x40, 0x40, 0x40, 0x40, 0x40,
            0x00, 0x03, 0x07, 0x08, 0x00,
            0x20, 0x54, 0x54, 0x78, 0x40,
            0x7F, 0x28, 0x44, 0x44, 0x38,
            0x38, 0x44, 0x44, 0x44, 0x28,
            0x38, 0x44, 0x44, 0x28, 0x7F,
            0x38, 0x54, 0x54, 0x54, 0x18,
            0x00, 0x08, 0x7E, 0x09, 0x02,
            0x18, 0xA4, 0xA4, 0x9C, 0x78,
            0x7F, 0x08, 0x04, 0x04, 0x78,
            0x00, 0x44, 0x7D, 0x40, 0x00,
            0x20, 0x40, 0x40, 0x3D, 0x00,
            0x7F, 0x10, 0x28, 0x44, 0x00,
            0x00, 0x41, 0x7F, 0x40, 0x00,
            0x7C, 0x04, 0x78, 0x04, 0x78,
            0x7C, 0x08, 0x04, 0x04, 0x78,
            0x38, 0x44, 0x44, 0x44, 0x38,
            0xFC, 0x18, 0x24, 0x24, 0x18,
            0x18, 0x24, 0x24, 0x18, 0xFC,
            0x7C, 0x08, 0x04, 0x04, 0x08,
            0x48, 0x54, 0x54, 0x54, 0x24,
            0x04, 0x04, 0x3F, 0x44, 0x24,
            0x3C, 0x40, 0x40, 0x20, 0x7C,
            0x1C, 0x20, 0x40, 0x20, 0x1C,
            0x3C, 0x40, 0x30, 0x40, 0x3C,
            0x44, 0x28, 0x10, 0x28, 0x44,
            0x4C, 0x90, 0x90, 0x90, 0x7C,
            0x44, 0x64, 0x54, 0x4C, 0x44,
            0x00, 0x08, 0x36, 0x41, 0x00,
            0x00, 0x00, 0x77, 0x00, 0x00,
            0x00, 0x41, 0x36, 0x08, 0x00,
            0x02, 0x01, 0x02, 0x04, 0x02,
            0x3C, 0x26, 0x23, 0x26, 0x3C,
            0x1E, 0xA1, 0xA1, 0x61, 0x12,
            0x3A, 0x40, 0x40, 0x20, 0x7A,
            0x38, 0x54, 0x54, 0x55, 0x59,
            0x21, 0x55, 0x55, 0x79, 0x41,
            0x21, 0x54, 0x54, 0x78, 0x41,
            0x21, 0x55, 0x54, 0x78, 0x40,
            0x20, 0x54, 0x55, 0x79, 0x40,
            0x0C, 0x1E, 0x52, 0x72, 0x12,
            0x39, 0x55, 0x55, 0x55, 0x59,
            0x39, 0x54, 0x54, 0x54, 0x59,
            0x39, 0x55, 0x54, 0x54, 0x58,
            0x00, 0x00, 0x45, 0x7C, 0x41,
            0x00, 0x02, 0x45, 0x7D, 0x42,
            0x00, 0x01, 0x45, 0x7C, 0x40,
            0xF0, 0x29, 0x24, 0x29, 0xF0,
            0xF0, 0x28, 0x25, 0x28, 0xF0,
            0x7C, 0x54, 0x55, 0x45, 0x00,
            0x20, 0x54, 0x54, 0x7C, 0x54,
            0x7C, 0x0A, 0x09, 0x7F, 0x49,
            0x32, 0x49, 0x49, 0x49, 0x32,
            0x32, 0x48, 0x48, 0x48, 0x32,
            0x32, 0x4A, 0x48, 0x48, 0x30,
            0x3A, 0x41, 0x41, 0x21, 0x7A,
            0x3A, 0x42, 0x40, 0x20, 0x78,
            0x00, 0x9D, 0xA0, 0xA0, 0x7D,
            0x39, 0x44, 0x44, 0x44, 0x39,
            0x3D, 0x40, 0x40, 0x40, 0x3D,
            0x3C, 0x24, 0xFF, 0x24, 0x24,
            0x48, 0x7E, 0x49, 0x43, 0x66,
            0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
            0xFF, 0x09, 0x29, 0xF6, 0x20,
            0xC0, 0x88, 0x7E, 0x09, 0x03,
            0x20, 0x54, 0x54, 0x79, 0x41,
            0x00, 0x00, 0x44, 0x7D, 0x41,
            0x30, 0x48, 0x48, 0x4A, 0x32,
            0x38, 0x40, 0x40, 0x22, 0x7A,
            0x00, 0x7A, 0x0A, 0x0A, 0x72,
            0x7D, 0x0D, 0x19, 0x31, 0x7D,
            0x26, 0x29, 0x29, 0x2F, 0x28,
            0x26, 0x29, 0x29, 0x29, 0x26,
            0x30, 0x48, 0x4D, 0x40, 0x20,
            0x38, 0x08, 0x08, 0x08, 0x08,
            0x08, 0x08, 0x08, 0x08, 0x38,
            0x2F, 0x10, 0xC8, 0xAC, 0xBA,
            0x2F, 0x10, 0x28, 0x34, 0xFA,
            0x00, 0x00, 0x7B, 0x00, 0x00,
            0x08, 0x14, 0x2A, 0x14, 0x22,
            0x22, 0x14, 0x2A, 0x14, 0x08,
            0xAA, 0x00, 0x55, 0x00, 0xAA,
            0xAA, 0x55, 0xAA, 0x55, 0xAA,
            0x00, 0x00, 0x00, 0xFF, 0x00,
            0x10, 0x10, 0x10, 0xFF, 0x00,
            0x14, 0x14, 0x14, 0xFF, 0x00,
            0x10, 0x10, 0xFF, 0x00, 0xFF,
            0x10, 0x10, 0xF0, 0x10, 0xF0,
            0x14, 0x14, 0x14, 0xFC, 0x00,
            0x14, 0x14, 0xF7, 0x00, 0xFF,
            0x00, 0x00, 0xFF, 0x00, 0xFF,
            0x14, 0x14, 0xF4, 0x04, 0xFC,
            0x14, 0x14, 0x17, 0x10, 0x1F,
            0x10, 0x10, 0x1F, 0x10, 0x1F,
            0x14, 0x14, 0x14, 0x1F, 0x00,
            0x10, 0x10, 0x10, 0xF0, 0x00,
            0x00, 0x00, 0x00, 0x1F, 0x10,
            0x10, 0x10, 0x10, 0x1F, 0x10,
            0x10, 0x10, 0x10, 0xF0, 0x10,
            0x00, 0x00, 0x00, 0xFF, 0x10,
            0x10, 0x10, 0x10, 0x10, 0x10,
            0x10, 0x10, 0x10, 0xFF, 0x10,
            0x00, 0x00, 0x00, 0xFF, 0x14,
            0x00, 0x00, 0xFF, 0x00, 0xFF,
            0x00, 0x00, 0x1F, 0x10, 0x17,
            0x00, 0x00, 0xFC, 0x04, 0xF4,
            0x14, 0x14, 0x17, 0x10, 0x17,
            0x14, 0x14, 0xF4, 0x04, 0xF4,
            0x00, 0x00, 0xFF, 0x00, 0xF7,
            0x14, 0x14, 0x14, 0x14, 0x14,
            0x14, 0x14, 0xF7, 0x00, 0xF7,
            0x14, 0x14, 0x14, 0x17, 0x14,
            0x10, 0x10, 0x1F, 0x10, 0x1F,
            0x14, 0x14, 0x14, 0xF4, 0x14,
            0x10, 0x10, 0xF0, 0x10, 0xF0,
            0x00, 0x00, 0x1F, 0x10, 0x1F,
            0x00, 0x00, 0x00, 0x1F, 0x14,
            0x00, 0x00, 0x00, 0xFC, 0x14,
            0x00, 0x00, 0xF0, 0x10, 0xF0,
            0x10, 0x10, 0xFF, 0x10, 0xFF,
            0x14, 0x14, 0x14, 0xFF, 0x14,
            0x10, 0x10, 0x10, 0x1F, 0x00,
            0x00, 0x00, 0x00, 0xF0, 0x10,
            0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
            0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
            0xFF, 0xFF, 0xFF, 0x00, 0x00,
            0x00, 0x00, 0x00, 0xFF, 0xFF,
            0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
            0x38, 0x44, 0x44, 0x38, 0x44,
            0x7C, 0x2A, 0x2A, 0x3E, 0x14,
            0x7E, 0x02, 0x02, 0x06, 0x06,
            0x02, 0x7E, 0x02, 0x7E, 0x02,
            0x63, 0x55, 0x49, 0x41, 0x63,
            0x38, 0x44, 0x44, 0x3C, 0x04,
            0x40, 0x7E, 0x20, 0x1E, 0x20,
            0x06, 0x02, 0x7E, 0x02, 0x02,
            0x99, 0xA5, 0xE7, 0xA5, 0x99,
            0x1C, 0x2A, 0x49, 0x2A, 0x1C,
            0x4C, 0x72, 0x01, 0x72, 0x4C,
            0x30, 0x4A, 0x4D, 0x4D, 0x30,
            0x30, 0x48, 0x78, 0x48, 0x30,
            0xBC, 0x62, 0x5A, 0x46, 0x3D,
            0x3E, 0x49, 0x49, 0x49, 0x00,
            0x7E, 0x01, 0x01, 0x01, 0x7E,
            0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
            0x44, 0x44, 0x5F, 0x44, 0x44,
            0x40, 0x51, 0x4A, 0x44, 0x40,
            0x40, 0x44, 0x4A, 0x51, 0x40,
            0x00, 0x00, 0xFF, 0x01, 0x03,
            0xE0, 0x80, 0xFF, 0x00, 0x00,
            0x08, 0x08, 0x6B, 0x6B, 0x08,
            0x36, 0x12, 0x36, 0x24, 0x36,
            0x06, 0x0F, 0x09, 0x0F, 0x06,
            0x00, 0x00, 0x18, 0x18, 0x00,
            0x00, 0x00, 0x10, 0x10, 0x00,
            0x30, 0x40, 0xFF, 0x01, 0x01,
            0x00, 0x1F, 0x01, 0x01, 0x1E,
            0x00, 0x19, 0x1D, 0x17, 0x12,
            0x00, 0x3C, 0x3C, 0x3C, 0x3C,
            0x00, 0x00, 0x00, 0x00, 0x00]

    def getfont(self):
        return self.font


Finally... Test code
Code: Select all
#!/usr/bin/python

import time
from Adafruit_8x8 import EightByEight

MATRICES = 1
matrix = []

for i in range(0,MATRICES):
    matrix.append(EightByEight(address=0x70+i))
    matrix[i].setTextWrap(False) # Allow text to run off edges
    matrix[i].setRotation(3)
    matrix[i].setBrightness(7)

message = 'Hello World!'

# Horiz. position of text -- starts off right edge
x = 8 * MATRICES

while True:
    for i in range(0,MATRICES):
        # Draw message in each matrix buffer, offseting each by 8 pixels
        matrix[i].clear()
        matrix[i].setCursor(x - i * 8, 0)
        matrix[i].printMessage(message)
   
    # Write data to matrices in separate loop so it's less jumpy
    for i in range(0,MATRICES):
        matrix[i].writeDisplay()
       
    #print('Test')
   
    # Move text position left by 1 pixel.
    # When it's completely gone off left edge, start over off right.
    length = len(message) * 6
    x -= 1
    if(x < -(length)):
        x = 8 * MATRICES

    time.sleep(.25)


Here's a quick video showing the code in action.
http://youtu.be/t3RRYGigTZg
cameraready
 
Posts: 34
Joined: Wed Jan 30, 2013 10:10 pm

Re: 8x8 matrix sample python code

by cameraready on Fri Jun 07, 2013 11:06 pm

Fixed it! :D

After a little bit of debugging I found that the rotation checking code was misplaced. I also discovered that the method was not checking for x < 0 and y < 0.

Here is the corrected drawPixel method
Code: Select all
  def drawPixel(self, x, y, color=1):
    #"Sets a single pixel"
    if ((y < 0) or (y >= 8)):  # added y < 0
      return
    if ((x < 0) or (x >= 8)):  # added x < 0
      return   
     
    # Added rotation code 4/16/13 - RH
    if self.rotation == 1:
      x, y = self.swap(x, y)
      x = 8 - x - 1
    elif self.rotation == 2:
      x = 8 - x - 1
      y = 8 - y - 1
    elif self.rotation == 3:
      x, y = self.swap(x, y)
      y = 8 - y - 1

    x += 7   # ATTN: This might be a bug?  On the color matrix, this causes x=0 to draw on the last line instead of the first.
    x %= 8
    # Set the appropriate pixel
    buffer = self.getBuffer()
    if (color):
      self.setBufferRow(y, buffer[y] | 1 << x)
    else:
      self.setBufferRow(y, buffer[y] & ~(1 << x))


Quick video of the scrolling text.
http://youtu.be/XUOX5Q_4AFc
cameraready
 
Posts: 34
Joined: Wed Jan 30, 2013 10:10 pm

Re: 8x8 matrix sample python code

by cameraready on Wed Jun 19, 2013 9:12 pm

I tweaked the code a bit this week and have it working smoother now. The original drawPixel() method was updating the display by default which made it update after every pixel change. I also setup an account on github to share my modifications. I forked the Adafruit_Raspberry-Pi-Python-Code library and added my modifications.

https://github.com/cameraready/Adafruit-Raspberry-Pi-Python-Code
cameraready
 
Posts: 34
Joined: Wed Jan 30, 2013 10:10 pm