Last active
August 4, 2019 00:03
Revisions
-
TheRayTracer revised this gist
Aug 4, 2019 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -210,14 +210,14 @@ def __OpenSPI(self): return def __WriteCommand(self, data): if isinstance(data, list) or isinstance(data, tuple): gpio.output(self.dc, self.COMMAND) self.spi.xfer(data) return def __WriteData(self, data): if isinstance(data, list) or isinstance(data, tuple): gpio.output(self.dc, self.DATA) self.spi.xfer(data) return -
TheRayTracer revised this gist
Jan 18, 2019 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
TheRayTracer revised this gist
May 1, 2016 . No changes.There are no files selected for viewing
-
TheRayTracer revised this gist
Jan 31, 2016 . 4 changed files with 153 additions and 39 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,8 @@ import struct import spidev import sys import time import random import RPi.GPIO as gpio ascii = [ @@ -134,9 +136,11 @@ [ 0x55, 0x00, 0x55, 0x00, 0x55 ] ] MAX_WIDTH = 0x80 MAX_HEIGHT_FULL = 0x40 MAX_HEIGHT_HALF = 0x20 MAX_PAGE_FULL = 0x08 MAX_PAGE_HALF = 0x04 H_SCROLL_ENABLE_TOP = 0x01 H_SCROLL_ENABLE_BOTTOM = 0x02 @@ -145,6 +149,8 @@ MEMORY_MODE = 0x20 SET_COLUMN = 0x21 SET_PAGE = 0x22 SET_RIGHT_SCROLL = 0x26 SET_LEFT_SCROLL = 0x27 SET_START_LINE = 0x40 DEACTIVATE_SCROLLING = 0x2E @@ -153,7 +159,8 @@ SET_CONTRAST = 0x81 CHARGE_PUMP = 0x8D SET_SEGMENT_REMAP_A = 0xA0 SET_SEGMENT_REMAP_B = 0xA1 ENTIRE_DISPLAY_RESUME = 0xA4 ENTIRE_DISPLAY_ON = 0xA5 NORMAL_DISPLAY = 0xA6 @@ -167,18 +174,20 @@ SET_DISPLAY_OFFSET = 0xD3 SET_DISPLAY_CLOCK_DIV = 0xD5 SET_COM_PINS = 0xDA NO_OPERATION = 0xE3 class SSD1306: COMMAND = gpio.LOW DATA = gpio.HIGH def __init__(self, dc, rst, cs, page_size): self.page_size = page_size self.rst = rst self.dc = dc self.cs = cs self._buffer = [0] * (MAX_WIDTH * self.page_size) # Setup GPIO. gpio.setmode(gpio.BCM) gpio.setup(self.dc, gpio.OUT) @@ -213,52 +222,61 @@ def __WriteData(self, data): return def __Setup(self): gpio.output(self.cs, gpio.LOW) time.sleep(0.2) gpio.output(self.rst, gpio.LOW) time.sleep(0.2) gpio.output(self.rst, gpio.HIGH) time.sleep(0.2) self.__WriteCommand([DISPLAY_OFF]) if self.page_size == MAX_PAGE_FULL: self.__WriteCommand([SET_MULTIPLEX, 0x3F]) else: self.__WriteCommand([SET_MULTIPLEX, 0x1F]) self.__WriteCommand([SET_DISPLAY_OFFSET, 0x00]) self.__WriteCommand([SET_START_LINE]) self.__WriteCommand([SET_SEGMENT_REMAP_B]) self.__WriteCommand([SCAN_DIRECTION_UP]) if self.page_size == MAX_PAGE_FULL: self.__WriteCommand([SET_COM_PINS, 0x12]) else: self.__WriteCommand([SET_COM_PINS, 0x02]) self.__WriteCommand([SET_CONTRAST, 0x7F]) self.__WriteCommand([NORMAL_DISPLAY]) self.__WriteCommand([SET_DISPLAY_CLOCK_DIV, 0x80]) self.__WriteCommand([CHARGE_PUMP, 0x14]) # Enable Charge Pump. self.__WriteCommand([MEMORY_MODE, 0x00]) # Setup the address mode. self.__WriteCommand([SET_COLUMN, 0x00, 0x7F]) self.__WriteCommand([SET_PAGE, 0x00, self.page_size - 1]) self.__WriteCommand([DISPLAY_ON]) return def Reset(self): gpio.output(self.rst, gpio.LOW) time.sleep(0.2) gpio.output(self.rst, gpio.HIGH) return def Remove(self): gpio.cleanup() self.spi.close() return def DrawPixel(self, x, y): page_offset = (y / 8) * MAX_WIDTH t = 0x01 << (y % 8) self._buffer[page_offset + x] |= t return def DrawHorizontalLine(self, y): page_offset = (y / 8) * MAX_WIDTH t = 0x01 << (y % 8) for i in xrange(0, MAX_WIDTH, 1): self._buffer[page_offset + i] |= t return def DrawVerticalLine(self, x): for i in xrange(0, self.page_size, 1): self._buffer[(i * MAX_WIDTH) + x] = 0xFF return @@ -343,7 +361,7 @@ def DrawString(self, x, y, str): return def Clear(self): for i in xrange(0, MAX_WIDTH * self.page_size, 1): self._buffer[i] = 0x00 return @@ -367,11 +385,11 @@ def EnableDisplay(self, enable): def SetScrollMode(self, horizontal): if horizontal == H_SCROLL_ENABLE_TOP: self.__WriteCommand([SET_RIGHT_SCROLL, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFF]) elif horizontal == H_SCROLL_ENABLE_BOTTOM: self.__WriteCommand([SET_RIGHT_SCROLL, 0x00, 0x02, 0x00, self.page_size - 1, 0x00, 0xFF]) elif horizontal == H_SCROLL_ENABLE_ALL: self.__WriteCommand([SET_RIGHT_SCROLL, 0x00, 0x00, 0x00, self.page_size - 1, 0x00, 0xFF]) return def EnableScrollMode(self, enable): @@ -392,7 +410,10 @@ def TestModeTest(self): def LineTest(self): self.Clear() m = 8 if self.page_size == MAX_PAGE_FULL: m = 16 for y in xrange(0, m, 1): self.DrawHorizontalLine(y * 4) self.Flip() time.sleep(4) @@ -405,32 +426,44 @@ def LineTest(self): def ShapeTest(self): self.Clear() if self.page_size == MAX_PAGE_FULL: self.DrawCircle(20, 32, 16) self.DrawTriangle(47, 48, 79, 48, 63, 16) self.DrawRect(90, 16, 122, 48) else: self.DrawCircle(20, 16, 14) self.DrawTriangle(47, 30, 79, 30, 63, 2) self.DrawRect(92, 2, 120, 30) self.Flip() time.sleep(8) return def CharTest(self): self.Clear() if self.page_size == MAX_PAGE_FULL: i = 48 for k in xrange(0, 16, 1): self.DrawChar(k * 8, 4, chr(i)) i = i + 1 i = 32 for j in xrange(0, 6, 1): for k in xrange(0, 16, 1): self.DrawChar(k * 8, j * 8 + 16, chr(i)) i = i + 1 else: i = 32 for j in xrange(0, 4, 1): for k in xrange(0, 16, 1): self.DrawChar(k * 8, j * 8, chr(i)) i = i + 1 self.Flip() time.sleep(8) return def ScrollTest(self): self.Clear() self.DrawString(4, 2, "Scrolling Test") self.DrawString(4, 18, "Scrolling Test") self.Flip() self.SetScrollMode(H_SCROLL_ENABLE_TOP) self.EnableScrollMode(True) @@ -451,7 +484,7 @@ def ScrollTest(self): SSD1306_PIN_RST = 25 if __name__ == '__main__': device = SSD1306(SSD1306_PIN_DC, SSD1306_PIN_RST, SSD1306_PIN_CS, MAX_PAGE_FULL) try: device.EnableDisplay(True) device.TestModeTest() LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,81 @@ import time import random import SSD1306 import RPi.GPIO as gpio class Dice: def __init__(self, device): self._device = device self._face = random.randint(1, 6) def Draw(self, i, debug): device.DrawRect(32 * i + 2, 2, 32 * i + 28, 30) if debug == True: device.DrawChar(32 * i + 13, 12, chr(self._face + 48)) else: if self._face == 1: device.DrawRect(32 * i + 14, 14, 32 * i + 16, 16) elif self._face == 2: device.DrawRect(32 * i + 7, 7, 32 * i + 9, 9) device.DrawRect(32 * i + 21, 21, 32 * i + 23, 23) elif self._face == 3: device.DrawRect(32 * i + 7, 7, 32 * i + 9, 9) device.DrawRect(32 * i + 14, 14, 32 * i + 16, 16) device.DrawRect(32 * i + 21, 21, 32 * i + 23, 23) elif self._face == 4: device.DrawRect(32 * i + 7, 7, 32 * i + 9, 9) device.DrawRect(32 * i + 21, 7, 32 * i + 23, 9) device.DrawRect(32 * i + 7, 21, 32 * i + 9, 23) device.DrawRect(32 * i + 21, 21, 32 * i + 23, 23) elif self._face == 5: device.DrawRect(32 * i + 14, 14, 32 * i + 16, 16) device.DrawRect(32 * i + 7, 7, 32 * i + 9, 9) device.DrawRect(32 * i + 21, 7, 32 * i + 23, 9) device.DrawRect(32 * i + 7, 21, 32 * i + 9, 23) device.DrawRect(32 * i + 21, 21, 32 * i + 23, 23) elif self._face == 6: device.DrawRect(32 * i + 7, 7, 32 * i + 9, 9) device.DrawRect(32 * i + 21, 7, 32 * i + 23, 9) device.DrawRect(32 * i + 7, 14, 32 * i + 9, 16) device.DrawRect(32 * i + 21, 14, 32 * i + 23, 16) device.DrawRect(32 * i + 7, 21, 32 * i + 9, 23) device.DrawRect(32 * i + 21, 21, 32 * i + 23, 23) return def Roll(self): self._face = random.randint(1, 6) return DUMMY_PIN_A = 23 SSD1306_PIN_DC = 24 DUMMY_PIN_B = 25 BUTTON_PIN = 25 MAX_DICE = 4 if __name__ == '__main__': device = SSD1306.SSD1306(SSD1306_PIN_DC, DUMMY_PIN_B, DUMMY_PIN_A, SSD1306.MAX_PAGE_HALF) gpio.setup(BUTTON_PIN, gpio.IN, pull_up_down = gpio.PUD_UP) dice = Dice(device) try: device.EnableDisplay(True) device.Clear() for i in xrange(0, MAX_DICE, 1): dice.Roll() dice.Draw(i, False) device.Flip() while True: input_state = gpio.input(BUTTON_PIN) if input_state == False: device.Clear() device.Flip() time.sleep(0.1) for i in xrange(0, MAX_DICE, 1): dice.Roll() dice.Draw(i, False) device.Flip() time.sleep(1.0) finally: device.EnableDisplay(False) device.Remove() -
TheRayTracer revised this gist
Dec 30, 2015 . 2 changed files with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
TheRayTracer revised this gist
Dec 29, 2015 . No changes.There are no files selected for viewing
-
TheRayTracer created this gist
Dec 29, 2015 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,464 @@ import spidev import sys import time import RPi.GPIO as gpio ascii = [ [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x55, 0x00, 0x55, 0x00, 0x55 ], [ 0x00, 0x00, 0x00, 0x00, 0x00 ], # sp [ 0x00, 0x00, 0x2f, 0x00, 0x00 ], # ! [ 0x00, 0x07, 0x00, 0x07, 0x00 ], # " [ 0x14, 0x7f, 0x14, 0x7f, 0x14 ], # # [ 0x24, 0x2a, 0x7f, 0x2a, 0x12 ], # $ [ 0x62, 0x64, 0x08, 0x13, 0x23 ], # % [ 0x36, 0x49, 0x55, 0x22, 0x50 ], # & [ 0x00, 0x05, 0x03, 0x00, 0x00 ], # ' [ 0x00, 0x1c, 0x22, 0x41, 0x00 ], # ( [ 0x00, 0x41, 0x22, 0x1c, 0x00 ], # ) [ 0x14, 0x08, 0x3E, 0x08, 0x14 ], # * [ 0x08, 0x08, 0x3E, 0x08, 0x08 ], # + [ 0x00, 0x00, 0xA0, 0x60, 0x00 ], # , [ 0x08, 0x08, 0x08, 0x08, 0x08 ], # - [ 0x00, 0x60, 0x60, 0x00, 0x00 ], # . [ 0x20, 0x10, 0x08, 0x04, 0x02 ], # / [ 0x3E, 0x51, 0x49, 0x45, 0x3E ], # 0 [ 0x00, 0x42, 0x7F, 0x40, 0x00 ], # 1 [ 0x42, 0x61, 0x51, 0x49, 0x46 ], # 2 [ 0x21, 0x41, 0x45, 0x4B, 0x31 ], # 3 [ 0x18, 0x14, 0x12, 0x7F, 0x10 ], # 4 [ 0x27, 0x45, 0x45, 0x45, 0x39 ], # 5 [ 0x3C, 0x4A, 0x49, 0x49, 0x30 ], # 6 [ 0x01, 0x71, 0x09, 0x05, 0x03 ], # 7 [ 0x36, 0x49, 0x49, 0x49, 0x36 ], # 8 [ 0x06, 0x49, 0x49, 0x29, 0x1E ], # 9 [ 0x00, 0x36, 0x36, 0x00, 0x00 ], # : [ 0x00, 0x56, 0x36, 0x00, 0x00 ], # ; [ 0x08, 0x14, 0x22, 0x41, 0x00 ], # < [ 0x14, 0x14, 0x14, 0x14, 0x14 ], # = [ 0x00, 0x41, 0x22, 0x14, 0x08 ], # > [ 0x02, 0x01, 0x51, 0x09, 0x06 ], # ? [ 0x32, 0x49, 0x59, 0x51, 0x3E ], # @ [ 0x7C, 0x12, 0x11, 0x12, 0x7C ], # A [ 0x7F, 0x49, 0x49, 0x49, 0x36 ], # B [ 0x3E, 0x41, 0x41, 0x41, 0x22 ], # C [ 0x7F, 0x41, 0x41, 0x22, 0x1C ], # D [ 0x7F, 0x49, 0x49, 0x49, 0x41 ], # E [ 0x7F, 0x09, 0x09, 0x09, 0x01 ], # F [ 0x3E, 0x41, 0x49, 0x49, 0x7A ], # G [ 0x7F, 0x08, 0x08, 0x08, 0x7F ], # H [ 0x00, 0x41, 0x7F, 0x41, 0x00 ], # I [ 0x20, 0x40, 0x41, 0x3F, 0x01 ], # J [ 0x7F, 0x08, 0x14, 0x22, 0x41 ], # K [ 0x7F, 0x40, 0x40, 0x40, 0x40 ], # L [ 0x7F, 0x02, 0x0C, 0x02, 0x7F ], # M [ 0x7F, 0x04, 0x08, 0x10, 0x7F ], # N [ 0x3E, 0x41, 0x41, 0x41, 0x3E ], # O [ 0x7F, 0x09, 0x09, 0x09, 0x06 ], # P [ 0x3E, 0x41, 0x51, 0x21, 0x5E ], # Q [ 0x7F, 0x09, 0x19, 0x29, 0x46 ], # R [ 0x46, 0x49, 0x49, 0x49, 0x31 ], # S [ 0x01, 0x01, 0x7F, 0x01, 0x01 ], # T [ 0x3F, 0x40, 0x40, 0x40, 0x3F ], # U [ 0x1F, 0x20, 0x40, 0x20, 0x1F ], # V [ 0x3F, 0x40, 0x38, 0x40, 0x3F ], # W [ 0x63, 0x14, 0x08, 0x14, 0x63 ], # X [ 0x07, 0x08, 0x70, 0x08, 0x07 ], # Y [ 0x61, 0x51, 0x49, 0x45, 0x43 ], # Z [ 0x00, 0x7F, 0x41, 0x41, 0x00 ], # [ [ 0x02, 0x04, 0x08, 0x10, 0x20 ], # \ [ 0x00, 0x41, 0x41, 0x7F, 0x00 ], # ] [ 0x04, 0x02, 0x01, 0x02, 0x04 ], # ^ [ 0x40, 0x40, 0x40, 0x40, 0x40 ], # _ [ 0x00, 0x03, 0x02, 0x04, 0x00 ], # ' [ 0x20, 0x54, 0x54, 0x54, 0x78 ], # a [ 0x7F, 0x48, 0x44, 0x44, 0x38 ], # b [ 0x38, 0x44, 0x44, 0x44, 0x20 ], # c [ 0x38, 0x44, 0x44, 0x48, 0x7F ], # d [ 0x38, 0x54, 0x54, 0x54, 0x18 ], # e [ 0x08, 0x7E, 0x09, 0x01, 0x02 ], # f [ 0x18, 0xA4, 0xA4, 0xA4, 0x7C ], # g [ 0x7F, 0x08, 0x04, 0x04, 0x78 ], # h [ 0x00, 0x44, 0x7D, 0x40, 0x00 ], # i [ 0x40, 0x80, 0x84, 0x7D, 0x00 ], # j [ 0x7F, 0x10, 0x28, 0x44, 0x00 ], # k [ 0x00, 0x41, 0x7F, 0x40, 0x00 ], # l [ 0x7C, 0x04, 0x18, 0x04, 0x78 ], # m [ 0x7C, 0x08, 0x04, 0x04, 0x78 ], # n [ 0x38, 0x44, 0x44, 0x44, 0x38 ], # o [ 0xFC, 0x24, 0x24, 0x24, 0x18 ], # p [ 0x18, 0x24, 0x24, 0x18, 0xFC ], # q [ 0x7C, 0x08, 0x04, 0x04, 0x08 ], # r [ 0x48, 0x54, 0x54, 0x54, 0x20 ], # s [ 0x04, 0x3F, 0x44, 0x40, 0x20 ], # t [ 0x3C, 0x40, 0x40, 0x20, 0x7C ], # u [ 0x1C, 0x20, 0x40, 0x20, 0x1C ], # v [ 0x3C, 0x40, 0x30, 0x40, 0x3C ], # w [ 0x44, 0x28, 0x10, 0x28, 0x44 ], # x [ 0x1C, 0xA0, 0xA0, 0xA0, 0x7C ], # y [ 0x44, 0x64, 0x54, 0x4C, 0x44 ], # z [ 0x00, 0x08, 0x36, 0x41, 0x00 ], # { [ 0x00, 0x00, 0x77, 0x00, 0x00 ], # | [ 0x00, 0x41, 0x36, 0x08, 0x00 ], # } [ 0x02, 0x01, 0x02, 0x04, 0x02 ], # ~ [ 0x55, 0x00, 0x55, 0x00, 0x55 ] ] MAX_WIDTH = 0x80 MAX_HEIGHT = 0x40 MAX_PAGE = 0x08 H_SCROLL_ENABLE_TOP = 0x01 H_SCROLL_ENABLE_BOTTOM = 0x02 H_SCROLL_ENABLE_ALL = 0x04 MEMORY_MODE = 0x20 SET_COLUMN = 0x21 SET_PAGE = 0x22 SET_START_LINE = 0x40 DEACTIVATE_SCROLLING = 0x2E ACTIVATE_SCROLLING = 0x2F SET_CONTRAST = 0x81 CHARGE_PUMP = 0x8D SET_SEGMENT_REMAP = 0xA1 ENTIRE_DISPLAY_RESUME = 0xA4 ENTIRE_DISPLAY_ON = 0xA5 NORMAL_DISPLAY = 0xA6 INVERSE_DISPLAY = 0xA7 SET_MULTIPLEX = 0xA8 DISPLAY_OFF = 0xAE DISPLAY_ON = 0xAF SCAN_DIRECTION_DOWN = 0xC0 SCAN_DIRECTION_UP = 0xC8 SET_DISPLAY_OFFSET = 0xD3 SET_DISPLAY_CLOCK_DIV = 0xD5 NO_OPERATION = 0xE3 class SSD1306: COMMAND = gpio.LOW DATA = gpio.HIGH def __init__(self, dc, rst, cs): self.rst = rst self.dc = dc self.cs = cs self._buffer = [0] * (MAX_WIDTH * MAX_PAGE) # Setup GPIO. gpio.setmode(gpio.BCM) gpio.setup(self.dc, gpio.OUT) gpio.output(self.dc, gpio.LOW) gpio.setup(self.rst, gpio.OUT) gpio.output(self.rst, gpio.HIGH) gpio.setup(self.cs, gpio.OUT) gpio.output(self.cs, gpio.HIGH) self.__OpenSPI() # Setup SPI. self.__Setup() # Setup device screen. self.Clear() # Blank the screen. return def __OpenSPI(self): self.spi = spidev.SpiDev() self.spi.open(0, 0) self.spi.mode = 3 self.spi.max_speed_hz = 9000000 self.spi.cshigh = False return def __WriteCommand(self, data): gpio.output(self.dc, self.COMMAND) if isinstance(data, list) or isinstance(data, tuple): self.spi.xfer(data) return def __WriteData(self, data): gpio.output(self.dc, self.DATA) if isinstance(data, list) or isinstance(data, tuple): self.spi.xfer(data) return def __Setup(self): self.spi.cshigh = True self.spi.xfer([0]) gpio.output(self.cs, gpio.LOW) time.sleep(0.1) gpio.output(self.rst, gpio.LOW) time.sleep(0.5) gpio.output(self.rst, gpio.HIGH) time.sleep(0.5) self.spi.cshigh = False self.spi.xfer([0]) self.__WriteCommand([DISPLAY_OFF]) self.__WriteCommand([SET_MULTIPLEX, 0x3F]) self.__WriteCommand([SET_DISPLAY_OFFSET, 0x00]) self.__WriteCommand([SET_START_LINE]) self.__WriteCommand([SET_SEGMENT_REMAP]) self.__WriteCommand([SET_CONTRAST, 0x7F]) self.__WriteCommand([NORMAL_DISPLAY]) self.__WriteCommand([SET_DISPLAY_CLOCK_DIV, 0x80]) self.__WriteCommand([CHARGE_PUMP, 0x14]) # Enable Charge Pump. self.__WriteCommand([SCAN_DIRECTION_UP]) self.__WriteCommand([MEMORY_MODE, 0x00]) # Setup the address mode. self.__WriteCommand([SET_COLUMN, 0x00, 0x7F]) self.__WriteCommand([SET_PAGE, 0x00, 0x07]) self.__WriteCommand([DISPLAY_ON]) return def Remove(self): gpio.cleanup() self.spi.close() return def DrawPixel(self, x, y): page_offset = (y / MAX_PAGE) * MAX_WIDTH t = 0x01 << (y % MAX_PAGE) self._buffer[page_offset + x] |= t return def DrawHorizontalLine(self, y): page_offset = (y / MAX_PAGE) * MAX_WIDTH t = 0x01 << (y % MAX_PAGE) for i in xrange(0, MAX_WIDTH, 1): self._buffer[page_offset + i] |= t return def DrawVerticalLine(self, x): for i in xrange(0, MAX_PAGE, 1): self._buffer[(i * MAX_WIDTH) + x] = 0xFF return # Bresenham's line algorithm. def DrawLine(self, x0, y0, x1, y1): dx = x1 - x0 if dx < 0: dx = x0 - x1 sx = -1 if x0 < x1: sx = 1 dy = y1 - y0 if dy < 0: dy = y0 - y1 sy = -1 if y0 < y1: sy = 1 err = -dy / 2 if dy < dx: err = dx / 2 self.DrawPixel(x0, y0) while x0 != x1 or y0 != y1: e2 = err if e2 > -dx: err = err - dy x0 = x0 + sx if e2 < dy: err = err + dx y0 = y0 + sy self.DrawPixel(x0, y0) return def DrawTriangle(self, x0, y0, x1, y1, x2, y2): self.DrawLine(x0, y0, x1, y1) self.DrawLine(x1, y1, x2, y2) self.DrawLine(x0, y0, x2, y2) return def DrawRect(self, x0, y0, x1, y1): self.DrawLine(x0, y0, x1, y0) self.DrawLine(x1, y0, x1, y1) self.DrawLine(x1, y1, x0, y1) self.DrawLine(x0, y1, x0, y0) return def DrawCircle(self, x0, y0, r0): x = r0 y = 0 decision_over2 = 1 - x # Decision criterion divided by 2 evaluated at x = r, y = 0. while y <= x: self.DrawPixel( x + x0, y + y0) # Octant 1. self.DrawPixel( y + x0, x + y0) # Octant 2. self.DrawPixel(-x + x0, y + y0) # Octant 4. self.DrawPixel(-y + x0, x + y0) # Octant 3. self.DrawPixel(-x + x0, -y + y0) # Octant 5. self.DrawPixel(-y + x0, -x + y0) # Octant 6. self.DrawPixel( x + x0, -y + y0) # Octant 8. self.DrawPixel( y + x0, -x + y0) # Octant 7. y = y + 1 if decision_over2 <= 0: decision_over2 = decision_over2 + 2 * y + 1 # Change in decision criterion for y -> y + 1. else: x = x - 1 decision_over2 = decision_over2 + 2 * (y - x) + 1 # Change for y -> y + 1, x -> x - 1. return def DrawChar(self, x, y, ch): for i in xrange(0, 5, 1): line = ascii[ord(ch) & 0x7F][i] for j in xrange(0, 8, 1): if line & 0x1: self.DrawPixel(x + i, y + j) line >>= 1 return def DrawString(self, x, y, str): for i in str: if x > 0x5F: break self.DrawChar(x, y, i) x = x + 6 return def Clear(self): for i in xrange(0, MAX_WIDTH * MAX_PAGE, 1): self._buffer[i] = 0x00 return def Flip(self): self.__WriteData(self._buffer) return def TestEntireDisplay(self, enable): if enable: self.__WriteCommand([ENTIRE_DISPLAY_ON]) else: self.__WriteCommand([ENTIRE_DISPLAY_RESUME]) return def EnableDisplay(self, enable): if enable: self.__WriteCommand([DISPLAY_ON]) else: self.__WriteCommand([DISPLAY_OFF]) return def SetScrollMode(self, horizontal): if horizontal == H_SCROLL_ENABLE_TOP: self.__WriteCommand([0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFF]) elif horizontal == H_SCROLL_ENABLE_BOTTOM: self.__WriteCommand([0x26, 0x00, 0x02, 0x00, 0x07, 0x00, 0xFF]) elif horizontal == H_SCROLL_ENABLE_ALL: self.__WriteCommand([0x26, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF]) return def EnableScrollMode(self, enable): if enable: self.__WriteCommand([ACTIVATE_SCROLLING]) else: self.__WriteCommand([DEACTIVATE_SCROLLING]) return def TestModeTest(self): device.TestEntireDisplay(True) time.sleep(4) device.Clear() device.Flip() device.TestEntireDisplay(False) time.sleep(2) return def LineTest(self): self.Clear() for y in xrange(0, 16, 1): self.DrawHorizontalLine(y * 4) self.Flip() time.sleep(4) self.Clear() for x in xrange(0, 32, 1): self.DrawVerticalLine(x * 4) self.Flip() time.sleep(4) return def ShapeTest(self): self.Clear() self.DrawCircle(20, 32, 16) self.DrawTriangle(47, 48, 79, 48, 63, 16) self.DrawRect(90, 16, 122, 48) self.Flip() time.sleep(8) return def CharTest(self): self.Clear() i = 48 for k in xrange(0, 16, 1): self.DrawChar(k * 8, 4, chr(i)) i = i + 1 i = 32 for j in xrange(0, 6, 1): for k in xrange(0, 16, 1): self.DrawChar(k * 8, j * 8 + 16, chr(i)) i = i + 1 self.Flip() time.sleep(8) return def ScrollTest(self): self.Clear() self.DrawString(4, 2, "Scrolling Test") self.DrawString(4, 28, "Scrolling Test") self.Flip() self.SetScrollMode(H_SCROLL_ENABLE_TOP) self.EnableScrollMode(True) time.sleep(10) self.EnableScrollMode(False) self.SetScrollMode(H_SCROLL_ENABLE_BOTTOM) self.EnableScrollMode(True) time.sleep(10) self.EnableScrollMode(False) self.SetScrollMode(H_SCROLL_ENABLE_ALL) self.EnableScrollMode(True) time.sleep(10) self.EnableScrollMode(False) return SSD1306_PIN_CS = 23 SSD1306_PIN_DC = 24 SSD1306_PIN_RST = 25 if __name__ == '__main__': device = SSD1306(SSD1306_PIN_DC, SSD1306_PIN_RST, SSD1306_PIN_CS) try: device.EnableDisplay(True) device.TestModeTest() device.LineTest() device.ShapeTest() device.ScrollTest() device.CharTest() device.EnableDisplay(False) finally: device.Remove()