Merge pull request #34 from pimoroni/patch-v1.0.0-prep

Tidyup, bugfixes and prep for v1.0.0
This commit is contained in:
Philip Howard
2023-11-15 10:28:15 +00:00
committed by GitHub
13 changed files with 77 additions and 156 deletions

View File

@@ -1,3 +1,9 @@
1.0.0
-----
* Rename module from ST7735 to st7735
* Port to gpiod/gpiodevice
0.0.5
-----

View File

@@ -31,23 +31,23 @@ SPI_SPEED_MHZ = 4 # Higher speed = higher framerate
if len(sys.argv) > 1:
SPI_SPEED_MHZ = int(sys.argv[1])
print("""
print(f"""
framerate.py - Test LCD framerate.
If you're using Breakout Garden, plug the 0.96" LCD (SPI)
breakout into the rear slot.
Running at: {}MHz
""".format(SPI_SPEED_MHZ))
Running at: {SPI_SPEED_MHZ}MHz
""")
# Create ST7735 LCD display class.
disp = st7735.ST7735(
port=0,
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="PIN21",
backlight="PIN35", # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CS_BACK or BG_SPI_CS_FRONT. BG_SPI_CS_FRONT (eg: CE1) for Enviro Plus
dc="PIN21", # "GPIO9" / "PIN21". "PIN21" for a Pi 5 with Enviro Plus
backlight="PIN32", # "PIN18" for back BG slot, "PIN19" for front BG slot. "PIN32" for a Pi 5 with Enviro Plus
rotation=90,
spi_speed_hz=SPI_SPEED_MHZ * 1000000
spi_speed_hz=4000000
)
WIDTH = disp.width
@@ -78,7 +78,4 @@ while True:
count += 1
time_current = time.time() - time_start
if count % 120 == 0:
print("Time: {:8.3f}, Frames: {:6d}, FPS: {:8.3f}".format(
time_current,
count,
count / time_current))
print(f"Time: {time_current:8.3f}, Frames: {count:6d}, FPS: {count / time_current:8.3f}")

View File

@@ -35,15 +35,16 @@ breakout into the front slot.
if len(sys.argv) > 1:
image_file = sys.argv[1]
else:
print("Usage: {} <filename.gif>".format(sys.argv[0]))
print(f"Usage: {sys.argv[0]} <filename.gif>")
sys.exit(0)
# Create TFT LCD display class.
disp = st7735.ST7735(
port=0,
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CS_BACK or BG_SPI_CS_FRONT. BG_SPI_CS_FRONT (eg: CE1) for Enviro Plus
dc="PIN21", # "GPIO9" / "PIN21". "PIN21" for a Pi 5 with Enviro Plus
backlight="PIN32", # "PIN18" for back BG slot, "PIN19" for front BG slot. "PIN32" for a Pi 5 with Enviro Plus
rotation=90,
spi_speed_hz=4000000
)
@@ -54,10 +55,10 @@ width = disp.width
height = disp.height
# Load an image.
print('Loading gif: {}...'.format(image_file))
print(f"Loading gif: {image_file}...")
image = Image.open(image_file)
print('Drawing gif, press Ctrl+C to exit!')
print("Drawing gif, press Ctrl+C to exit!")
frame = 0

View File

@@ -32,7 +32,7 @@ breakout into the rear slot.
""")
if len(sys.argv) < 2:
print("Usage: {} <image_file>".format(sys.argv[0]))
print(f"Usage: {sys.argv[0]} <image_file>")
sys.exit(1)
image_file = sys.argv[1]
@@ -40,9 +40,9 @@ image_file = sys.argv[1]
# Create ST7735 LCD display class.
disp = st7735.ST7735(
port=0,
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CS_BACK or BG_SPI_CS_FRONT. BG_SPI_CS_FRONT (eg: CE1) for Enviro Plus
dc="PIN21", # "GPIO9" / "PIN21". "PIN21" for a Pi 5 with Enviro Plus
backlight="PIN32", # "PIN18" for back BG slot, "PIN19" for front BG slot. "PIN32" for a Pi 5 with Enviro Plus
rotation=90,
spi_speed_hz=4000000
)
@@ -54,13 +54,13 @@ HEIGHT = disp.height
disp.begin()
# Load an image.
print('Loading image: {}...'.format(image_file))
print(f"Loading image: {image_file}...")
image = Image.open(image_file)
# Resize the image
image = image.resize((WIDTH, HEIGHT))
# Draw the image on the display hardware.
print('Drawing image')
print("Drawing image")
disp.display(image)

View File

@@ -9,11 +9,11 @@ MESSAGE = "Hello World! How are you today?"
# Create ST7735 LCD display class.
disp = st7735.ST7735(
port=0,
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CS_BACK or BG_SPI_CS_FRONT. BG_SPI_CS_FRONT (eg: CE1) for Enviro Plus
dc="PIN21", # "GPIO9" / "PIN21". "PIN21" for a Pi 5 with Enviro Plus
backlight="PIN32", # "PIN18" for back BG slot, "PIN19" for front BG slot. "PIN32" for a Pi 5 with Enviro Plus
rotation=90,
spi_speed_hz=10000000
spi_speed_hz=4000000
)
# Initialize display.
@@ -29,7 +29,9 @@ draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 30)
size_x, size_y = draw.textsize(MESSAGE, font)
x1, y1, x2, y2 = font.getbbox(MESSAGE)
size_x = x2 - x1
size_y = y2 - y1
text_x = 160
text_y = (80 - size_y) // 2

View File

@@ -25,7 +25,7 @@ import st7735
print("""
shapes.py - Display test shapes on the LCD using PIL.
If you're using Breakout Garden, plug the 0.96" LCD (SPI)
If you"re using Breakout Garden, plug the 0.96" LCD (SPI)
breakout into the rear slot.
""")
@@ -33,9 +33,9 @@ breakout into the rear slot.
# Create ST7735 LCD display class.
disp = st7735.ST7735(
port=0,
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CS_BACK or BG_SPI_CS_FRONT. BG_SPI_CS_FRONT (eg: CE1) for Enviro Plus
dc="PIN21", # "GPIO9" / "PIN21". "PIN21" for a Pi 5 with Enviro Plus
backlight="PIN32", # "PIN18" for back BG slot, "PIN19" for front BG slot. "PIN32" for a Pi 5 with Enviro Plus
rotation=90,
spi_speed_hz=4000000
)
@@ -50,7 +50,7 @@ HEIGHT = disp.height
# Clear the display to a red background.
# Can pass any tuple of red, green, blue values (from 0 to 255 each).
# Get a PIL Draw object to start drawing on the display buffer.
img = Image.new('RGB', (WIDTH, HEIGHT), color=(255, 0, 0))
img = Image.new("RGB", (WIDTH, HEIGHT), color=(255, 0, 0))
draw = ImageDraw.Draw(img)
@@ -73,18 +73,19 @@ font = ImageFont.load_default()
# Alternatively load a TTF font.
# Some other nice fonts to try: http://www.dafont.com/bitmap.php
# font = ImageFont.truetype('Minecraftia.ttf', 16)
# font = ImageFont.truetype("Minecraftia.ttf", 16)
# Define a function to create rotated text. Unfortunately PIL doesn't have good
# Define a function to create rotated text. Unfortunately PIL doesn"t have good
# native support for rotated fonts, but this function can be used to make a
# text image and rotate it so it's easy to paste in the buffer.
# text image and rotate it so it"s easy to paste in the buffer.
def draw_rotated_text(image, text, position, angle, font, fill=(255, 255, 255)):
# Get rendered font width and height.
draw = ImageDraw.Draw(image)
width, height = draw.textsize(text, font=font)
x1, y1, x2, y2 = font.getbbox(text)
width = x2 - x1
height = y2 - y1
# Create a new image with transparent background to store the text.
textimage = Image.new('RGBA', (width, height), (0, 0, 0, 0))
textimage = Image.new("RGBA", (width, height), (0, 0, 0, 0))
# Render the text.
textdraw = ImageDraw.Draw(textimage)
textdraw.text((0, 0), text, font=font, fill=fill)
@@ -95,8 +96,8 @@ def draw_rotated_text(image, text, position, angle, font, fill=(255, 255, 255)):
# Write two lines of white text on the buffer, rotated 90 degrees counter clockwise.
draw_rotated_text(img, 'Hello World!', (0, 0), 90, font, fill=(255, 255, 255))
draw_rotated_text(img, 'This is a line of text.', (10, HEIGHT - 10), 0, font, fill=(255, 255, 255))
draw_rotated_text(img, "Hello World!", (0, 0), 90, font, fill=(255, 255, 255))
draw_rotated_text(img, "This is a line of text.", (10, HEIGHT - 10), 0, font, fill=(255, 255, 255))
# Write buffer to display hardware, must be called to make things visible on the
# display!

View File

@@ -36,7 +36,8 @@ classifiers = [
"Topic :: System :: Hardware",
]
dependencies = [
"spidev"
"spidev>=3.4",
"numpy"
]
[project.urls]
@@ -96,6 +97,9 @@ skip = """
[tool.isort]
line_length = 200
[tool.black]
line-length = 200
[tool.check-manifest]
ignore = [
'.stickler.yml',

View File

@@ -1,3 +1,3 @@
pillow
numpy
spidev
pillow>=10.0.0
numpy>=1.26.0
spidev>=3.4

View File

@@ -1,56 +0,0 @@
# -*- coding: utf-8 -*-
[metadata]
name = ST7735
version = 0.0.5
author = Philip Howard
author_email = phil@pimoroni.com
description = Library to control an ST7735 168x80 TFT LCD display.
long_description = file: README.md
long_description_content_type = text/markdown
keywords = Raspberry Pi
url = https://www.pimoroni.com
project_urls =
GitHub=https://www.github.com/pimoroni/st7735-python
license = MIT
# This includes the license file(s) in the wheel.
# https://wheel.readthedocs.io/en/stable/user_guide.html#including-license-files-in-the-generated-wheel-file
license_files = LICENSE.txt
classifiers =
Development Status :: 4 - Beta
Operating System :: POSIX :: Linux
License :: OSI Approved :: MIT License
Intended Audience :: Developers
Programming Language :: Python :: 3
Topic :: Software Development
Topic :: Software Development :: Libraries
Topic :: System :: Hardware
[options]
packages = ST7735
install_requires =
spidev >= 3.4
[flake8]
exclude =
.tox,
.eggs,
.git,
__pycache__,
build,
dist
ignore =
E501
[pimoroni]
py3only = false
py2deps =
python-pil
py3deps =
python3-pil
python3-numpy
python3-spidev
python3-rpi.gpio
configtxt =
commands =
printf "Setting up SPI...\n"
raspi-config nonint do_spi 0

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Copyright (c) 2016 Pimoroni
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
from pkg_resources import parse_version
from setuptools import __version__, setup
minimum_version = parse_version('30.4.0')
if parse_version(__version__) < minimum_version:
raise RuntimeError("Package setuptools must be at least version {}".format(minimum_version))
setup()

View File

@@ -27,7 +27,7 @@ import numpy as np
import spidev
from gpiod.line import Direction, Value
__version__ = '0.0.5'
__version__ = '1.0.0'
OUTL = gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.INACTIVE)

View File

@@ -8,44 +8,44 @@ import mock
import pytest
@pytest.fixture(scope='function', autouse=False)
@pytest.fixture(scope="function", autouse=False)
def st7735():
import st7735
yield st7735
del sys.modules['st7735']
del sys.modules["st7735"]
@pytest.fixture(scope='function', autouse=False)
@pytest.fixture(scope="function", autouse=False)
def gpiod():
"""Mock gpiod module."""
sys.modules['gpiod'] = mock.MagicMock()
sys.modules['gpiod.line'] = mock.MagicMock()
yield sys.modules['gpiod']
del sys.modules['gpiod']
sys.modules["gpiod"] = mock.MagicMock()
sys.modules["gpiod.line"] = mock.MagicMock()
yield sys.modules["gpiod"]
del sys.modules["gpiod"]
@pytest.fixture(scope='function', autouse=False)
@pytest.fixture(scope="function", autouse=False)
def gpiodevice():
"""Mock gpiodevice module."""
sys.modules['gpiodevice'] = mock.MagicMock()
sys.modules['gpiodevice'].get_pin.return_value = (mock.Mock(), 0)
yield sys.modules['gpiodevice']
del sys.modules['gpiodevice']
sys.modules["gpiodevice"] = mock.MagicMock()
sys.modules["gpiodevice"].get_pin.return_value = (mock.Mock(), 0)
yield sys.modules["gpiodevice"]
del sys.modules["gpiodevice"]
@pytest.fixture(scope='function', autouse=False)
@pytest.fixture(scope="function", autouse=False)
def spidev():
"""Mock spidev module."""
spidev = mock.MagicMock()
sys.modules['spidev'] = spidev
sys.modules["spidev"] = spidev
yield spidev
del sys.modules['spidev']
del sys.modules["spidev"]
@pytest.fixture(scope='function', autouse=False)
@pytest.fixture(scope="function", autouse=False)
def numpy():
"""Mock numpy module."""
numpy = mock.MagicMock()
sys.modules['numpy'] = numpy
sys.modules["numpy"] = numpy
yield numpy
del sys.modules['numpy']
del sys.modules["numpy"]

View File

@@ -18,14 +18,10 @@ def test_setup_with_backlight(gpiodevice, gpiod, spidev, numpy, st7735):
display.set_backlight(True)
gpiodevice.get_pin.assert_has_calls([
mock.call("GPIO4", "st7735-bl", st7735.OUTL)
], any_order=True)
gpiodevice.get_pin.assert_has_calls([mock.call("GPIO4", "st7735-bl", st7735.OUTL)], any_order=True)
def test_setup_with_reset(gpiodevice, gpiod, spidev, numpy, st7735):
_ = st7735.ST7735(port=0, cs=0, dc=24, rst="GPIO4")
gpiodevice.get_pin.assert_has_calls([
mock.call("GPIO4", "st7735-rst", st7735.OUTL)
], any_order=True)
gpiodevice.get_pin.assert_has_calls([mock.call("GPIO4", "st7735-rst", st7735.OUTL)], any_order=True)