From 0fb7133079ac549e394356b1d62d40d40fdadcc8 Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sat, 6 Oct 2018 14:44:24 +0800 Subject: [PATCH 1/4] Add default Python gitignore --- .gitignore | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6c73837 --- /dev/null +++ b/.gitignore @@ -0,0 +1,111 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json \ No newline at end of file From 9145cf2fc956a6374befa8f911e63f534595217b Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sat, 6 Oct 2018 14:48:54 +0800 Subject: [PATCH 2/4] Fixed python 3 support, simplified mocking --- example_bitmaps.py | 15 ++++++++++++--- example_clock.py | 18 +++++++++++++----- example_polygons.py | 20 +++++++++++++++----- st7565.py | 6 ++---- xglcd_font.py | 13 +++++++------ 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/example_bitmaps.py b/example_bitmaps.py index cfa839f..d27768b 100644 --- a/example_bitmaps.py +++ b/example_bitmaps.py @@ -1,12 +1,21 @@ -import st7565 from pygame import time + +from xglcd_font import XglcdFont + +from os import environ +if environ.get('MOCK_RPI') == 'true': + from soft_display import mock_gpio, Glcd + mock_gpio() +else: + from st7565 import Glcd + clock = time.Clock() -glcd = st7565.Glcd(rgb=[21, 20, 16]) +glcd = Glcd(rgb=[21, 20, 16]) glcd.init() glcd.set_backlight_color(0, 0, 100) -path = "/home/pi/Pi-ST7565/images/" +path = "./images/" # Use List comprehension to load raw bitmaps to list dogs = [glcd.load_bitmap(path + "dog{0}.raw".format(i)) for i in range(1,8)] diff --git a/example_clock.py b/example_clock.py index f14774f..0c74a79 100644 --- a/example_clock.py +++ b/example_clock.py @@ -1,10 +1,18 @@ -import st7565 -import xglcd_font as font import math import time +import sys -neato = font.XglcdFont('/home/pi/Pi-ST7565/fonts/Neato5x7.c', 5, 7) -glcd = st7565.Glcd(rgb=[21, 20, 16]) +from xglcd_font import XglcdFont + +from os import environ +if environ.get('MOCK_RPI') == 'true': + from soft_display import mock_gpio, Glcd + mock_gpio() +else: + from st7565 import Glcd + +neato = XglcdFont('./fonts/Neato5x7.c', 5, 7) +glcd = Glcd(rgb=[21, 20, 16]) glcd.init() x0, y0 = 63, 31 @@ -43,6 +51,6 @@ def draw_face(): glcd.draw_line(x0, y0, *get_face_xy(hour * 30 - 90, 20)) glcd.flip() while minute == int(time.strftime("%M")): - time.sleep(1) + time.sleep(100) diff --git a/example_polygons.py b/example_polygons.py index 636d51d..64cf451 100755 --- a/example_polygons.py +++ b/example_polygons.py @@ -1,15 +1,22 @@ -import st7565 -import xglcd_font as font from time import sleep -glcd = st7565.Glcd(rgb=[21, 20, 16]) +from xglcd_font import XglcdFont + +from os import environ +if environ.get('MOCK_RPI') == 'true': + from soft_display import mock_gpio, Glcd + mock_gpio() +else: + from st7565 import Glcd + +glcd = Glcd(rgb=[21, 20, 16]) glcd.init() glcd.set_backlight_color(0, 100, 0) x0, y0 = 40, 31 rout, rmid, rin = 30, 20, 10 incr = 2 -path = "/home/pi/Pi-ST7565/" -wendy = font.XglcdFont(path + 'fonts/Wendy7x8.c', 7, 8) +path = './' +wendy = XglcdFont(path + 'fonts/Wendy7x8.c', 7, 8) ship = glcd.load_bitmap(path + 'images/ship_38x29.raw', width=38, height=29, invert=True) @@ -31,3 +38,6 @@ sleep(.01) glcd.cleanup() + +while True: + sleep(1) diff --git a/st7565.py b/st7565.py index ca8ad69..d30eb12 100644 --- a/st7565.py +++ b/st7565.py @@ -659,9 +659,8 @@ def draw_polygon(self, sides, x0, y0, r, rotate=0, color=1): up to complete on a full pixel. Therefore diameter = 2 x r + 1. """ coords = np.empty(shape=[sides + 1, 2], dtype="float64") - n = np.arange(sides, dtype="float64") theta = math.radians(rotate) - for s in n: + for s in range(sides): t = 2.0 * math.pi * s / sides + theta coords[s, 0] = r * math.cos(t) + x0 coords[s, 1] = r * math.sin(t) + y0 @@ -686,10 +685,9 @@ def fill_polygon(self, sides, x0, y0, r, rotate=0, color=1, invert=False): if self.is_off_grid(x0 - r, y0 - r, x0 + r, y0 + r): return coords = np.empty(shape=[sides + 1, 2], dtype="float64") - n = np.arange(sides, dtype="float64") theta = math.radians(rotate) # Determine polygon coordinates - for s in n: + for s in range(sides): t = 2.0 * math.pi * s / sides + theta coords[s, 0] = r * math.cos(t) + x0 coords[s, 1] = r * math.sin(t) + y0 diff --git a/xglcd_font.py b/xglcd_font.py index 89243ff..533e314 100644 --- a/xglcd_font.py +++ b/xglcd_font.py @@ -41,21 +41,22 @@ def __load_xglcd_font(self, path): Numpy Array(Uint8): 2D - rows=letters, cols=letter bytes """ data = [] - with open(path, 'r') as f: + with open(path, 'rb') as f: for line in f: # Skip lines that do not start with hex values line = line.strip() - if len(line) == 0 or line[0:2] != '0x': + if len(line) == 0 or line[0:2] != b'0x': continue # Remove comments - comment = line.find('//') + comment = line.find(b'//') if comment != -1: line = line[0:comment].strip() # Remove trailing commas - if line.endswith(','): + if line.endswith(b','): line = line[0:len(line) - 1] - # Convert hex strings to integers and append - data.append([int(x, 16) for x in line.split(',')]) + # Convert hex strings to integers and append + + data.append([int(x, 16) for x in line.split(b',')]) return np.array(data).astype('uint8') From 47fb0c938b031d5b8deeadbf6b2f128f6d143d74 Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sat, 6 Oct 2018 14:54:26 +0800 Subject: [PATCH 3/4] Add updated info to Readme --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index a931436..97070b6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,31 @@ # Pi-ST7565 + ST7565 Graphics LCD Display Python Library for Raspberry Pi. Tested with Adafruit ST7565 module. Full tutorial on my website [Rototron](http://www.rototron.info/raspberry-pi-graphics-lcd-display-tutorial/) or click picture below for a YouTube video: [![ST7565 Tutorial](http://img.youtube.com/vi/Nn5u9xhHCTM/0.jpg)](https://youtu.be/Nn5u9xhHCTM) + +### Examples + +```bash +python example_polygons.py +``` + +When not running on an actual Raspberry Pi, use: + +```bash +MOCK_RPI=true python example_polygons.py +``` + +### Soft display + +To ease software development, you can use a software display, which uses pygame: + +```python +if os.environ.get('MOCK_RPI'): + from soft_display import mock_gpio, Glcd + mock_gpio() +else: + from st7565 import Glcd +``` \ No newline at end of file From fde153d6c0335219900aa41ce0b6c48a678f7c44 Mon Sep 17 00:00:00 2001 From: Hans Otto Wirtz Date: Sat, 6 Oct 2018 15:06:12 +0800 Subject: [PATCH 4/4] Fixed examples relative paths --- example_bitmaps.py | 7 ++++--- example_clock.py | 7 ++++--- example_polygons.py | 10 +++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/example_bitmaps.py b/example_bitmaps.py index d27768b..f635a1f 100644 --- a/example_bitmaps.py +++ b/example_bitmaps.py @@ -1,9 +1,10 @@ from pygame import time +import os +root = os.path.dirname(os.path.realpath(__file__)) from xglcd_font import XglcdFont -from os import environ -if environ.get('MOCK_RPI') == 'true': +if os.environ.get('MOCK_RPI') == 'true': from soft_display import mock_gpio, Glcd mock_gpio() else: @@ -15,7 +16,7 @@ glcd.init() glcd.set_backlight_color(0, 0, 100) -path = "./images/" +path = root + "/images/" # Use List comprehension to load raw bitmaps to list dogs = [glcd.load_bitmap(path + "dog{0}.raw".format(i)) for i in range(1,8)] diff --git a/example_clock.py b/example_clock.py index 0c74a79..6340547 100644 --- a/example_clock.py +++ b/example_clock.py @@ -1,17 +1,18 @@ import math import time import sys +import os +root = os.path.dirname(os.path.realpath(__file__)) from xglcd_font import XglcdFont -from os import environ -if environ.get('MOCK_RPI') == 'true': +if os.environ.get('MOCK_RPI') == 'true': from soft_display import mock_gpio, Glcd mock_gpio() else: from st7565 import Glcd -neato = XglcdFont('./fonts/Neato5x7.c', 5, 7) +neato = XglcdFont(root + '/fonts/Neato5x7.c', 5, 7) glcd = Glcd(rgb=[21, 20, 16]) glcd.init() x0, y0 = 63, 31 diff --git a/example_polygons.py b/example_polygons.py index 64cf451..fc47a88 100755 --- a/example_polygons.py +++ b/example_polygons.py @@ -1,9 +1,10 @@ from time import sleep +import os +root = os.path.dirname(os.path.realpath(__file__)) from xglcd_font import XglcdFont -from os import environ -if environ.get('MOCK_RPI') == 'true': +if os.environ.get('MOCK_RPI') == 'true': from soft_display import mock_gpio, Glcd mock_gpio() else: @@ -15,9 +16,8 @@ x0, y0 = 40, 31 rout, rmid, rin = 30, 20, 10 incr = 2 -path = './' -wendy = XglcdFont(path + 'fonts/Wendy7x8.c', 7, 8) -ship = glcd.load_bitmap(path + 'images/ship_38x29.raw', +wendy = XglcdFont(root + '/fonts/Wendy7x8.c', 7, 8) +ship = glcd.load_bitmap(root + '/images/ship_38x29.raw', width=38, height=29, invert=True) for angle in range(0, 360, incr):