Created
May 2, 2021 00:45
-
-
Save blakev/9af1b0a4534d5544ea57313d632bfa41 to your computer and use it in GitHub Desktop.
Simple Python3 "driver" for the WaveShare PoE Pi HAT with LCD display.
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 characters
import time | |
from typing import Optional, List | |
from PIL import Image | |
from PIL import ImageDraw | |
from PIL import ImageOps | |
from PIL import ImageFont | |
from smbus import SMBus | |
class LcdSSD1306: | |
FONT = ImageFont.truetype("fonts/type_writer.ttf", 7) | |
# https://www.dafont.com/type-writer.font | |
def __init__(self, width: int = 128, height: int = 32): | |
self._w = width | |
self._h = height | |
self._pages = int(self._h / 8) | |
self._addr = 0x3c # 60 | |
self._bus = SMBus(1) | |
self.__setup() | |
def __setup(self): | |
"""Bootstrap the display.""" | |
# yapf: disable | |
sequence = [ | |
0xAE, 0x40, 0xB0, 0xC8, 0x81, | |
0xFF, 0xA1, 0xA6, 0xA8, 0x1F, | |
0xD3, 0x00, 0xD5, 0xF0, 0xD9, | |
0x22, 0xDA, 0x02, 0xDB, 0x49, | |
0x8D, 0x14, 0xAF | |
] | |
# yapf: enable | |
for cmd in sequence: | |
self.write_cmd(cmd) | |
self.clear_black() | |
def write_cmd(self, cmd: int): | |
self._bus.write_byte_data(self._addr, 0x00, cmd) | |
def write_ram(self, cmd: int): | |
self._bus.write_byte_data(self._addr, 0x40, cmd) | |
def _put_buffer(self, *, color: Optional[int] = None, buffer: Optional[List[int]] = None,): | |
"""Writes pixels to the screen.""" | |
if color is None and buffer is None: | |
# no options | |
return | |
if color is not None and buffer: | |
# both options | |
return | |
if color is not None: | |
buffer = [color] * (self._h * self._w) | |
for p in range(self._pages): | |
self.write_cmd(0xB0 + p) | |
self.write_cmd(0x00) | |
self.write_cmd(0x10) | |
for c in range(self._w): | |
idx = c + self._w * p | |
new = buffer[idx] | |
self.write_ram(new) | |
def flash_image(self, image: Image, for_: float = 2.0, flip: bool = False): | |
"""Flashes a black and white image on the display for ``for_`` seconds.""" | |
image_a = image.convert('L') | |
image_b = ImageOps.invert(image_a) | |
start = time.monotonic() | |
self.clear_white() | |
while time.monotonic() < start + for_: | |
self.put_image(image_a, flip=flip) | |
self.put_image(image_b, flip=flip) | |
self.put_image(image_a, flip=flip) | |
self.clear_black() | |
def write_lines(self, *lines, flip: bool = False, invert: bool = False): | |
"""Write lines of text to the display.""" | |
if len(lines) == 1 and '\n' in lines[0]: | |
lines = lines[0].split('\n') | |
image = Image.new('L', (self._w, self._h), 'BLACK') | |
draw = ImageDraw.Draw(image) | |
for idx, line in enumerate(lines): | |
draw.text((0, (8 * idx)), str(line), font=self.FONT, fill='WHITE') | |
if invert: | |
image = ImageOps.invert(image) | |
self.put_image(image, flip=flip) | |
writelines = write_lines | |
def put_image(self, image: Image, flip: bool = False): | |
"""Puts a Pillow.Image buffer on the screen. | |
``flip`` will re-orient the image 180 degrees. | |
""" | |
# create a buffer for the contents that go on the screen | |
buffer = [0xff] * (self._pages * self._w) | |
# orient the image | |
if image.size == (self._h, self._w): | |
image = image.rotate(90, expand=True) | |
if flip: | |
image = image.rotate(180) | |
# convert image to monochromatic | |
mono = image.convert('1') | |
i_w, i_h = mono.size | |
pixels = mono.load() | |
# write the pixels to a horizontal screen | |
for y in range(i_h): | |
for x in range(i_w): | |
if pixels[x, y] == 0x00: | |
buffer[x + int(y / 8) * self._w] &= ~(1 << (y % 8)) | |
self._put_buffer(buffer=buffer) | |
def clear_white(self): | |
"""Fill the screen with white pixels.""" | |
self._put_buffer(color=0xFF) | |
def clear_black(self): | |
"""Fill the screen with black pixels.""" | |
self._put_buffer(color=0x00) | |
def close(self): | |
"""Safely close the I2C bus instance.""" | |
self._bus.close() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Link to the WaveShare Wiki.
Needs:
Also need to install this font, https://www.dafont.com/type-writer.font
Usage: