Skip to content

Commit

Permalink
Basic dual display example.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gadgetoid committed Nov 11, 2024
1 parent aba5f1f commit c0dcb1f
Showing 1 changed file with 122 additions and 0 deletions.
122 changes: 122 additions & 0 deletions examples/dual-displays.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/usr/bin/env python3
import colorsys
import math
import sys
import time

from PIL import Image, ImageDraw, ImageOps

import st7789

print(
f"""
dual-displays.py - A basic demo of driving two displays.
If you're using Breakout Garden-
- Plug a 1.3" ROUND LCD (SPI) breakout into the back slot.
- Plug a SQUARE LCD (SPI) breakout into the front.
Adjust the offset and settings below if you want to use
two round and two square.
Usage: {sys.argv[0]} <style>
Where style is one of:
* dots - swirly swooshy dots
* lines - 3D depth effect lines
The round (rear) LCD will be colour-inverted to
distinguish the two. Don't be alarmed!
"""
)

try:
style = sys.argv[1]
except IndexError:
style = "dots"

# Since we must share data/command between both displays
# and because libgpiod does not support sharing pins,
# we create it *once* here and pass the same pin *instance*
# (rather than pin number) to each display class constructor.
dc = st7789.ST7789.get_dc_pin(9)

# Create ST7789 LCD display class.
disp = st7789.ST7789(
port=0,
cs=st7789.BG_SPI_CS_FRONT, # BG_SPI_CS_BACK or BG_SPI_CS_FRONT
dc=dc,
backlight=19, # Breakout Garden: 18 for back slot, 19 for front slot.
# NOTE: Change this to 13 for Pirate Audio boards
rotation=90,
spi_speed_hz=80 * 1000 * 1000,
offset_left=0,
)

disp2 = st7789.ST7789(
port=0,
cs=st7789.BG_SPI_CS_BACK,
dc=dc,
backlight=18,
rotation=90,
spi_speed_hz=80 * 1000 * 1000,
offset_left=40
)

# Initialize display.
disp.begin()
disp2.begin()

RADIUS = disp.width // 2

img = Image.new("RGB", (disp.width, disp.height), color=(0, 0, 0))
draw = ImageDraw.Draw(img)


while True:
t = time.time()
draw.rectangle((0, 0, disp.width, disp.height), (0, 0, 0))
angle = t % (math.pi * 2)

prev_x = RADIUS
prev_y = RADIUS

steps = 100.0
angle_step = 1.0

if style == "lines":
steps *= 5
angle_step = 0.1

for step in range(int(steps)):
angle += angle_step

distance = RADIUS / steps * step
distance += step * 0.2

r, g, b = [
int(c * 255)
for c in colorsys.hsv_to_rgb((t / 10.0) + distance / 120.0, 1.0, 1.0)
]

x = RADIUS + int(distance * math.cos(angle))
y = RADIUS + int(distance * math.sin(angle))

line = ((math.sin(t + angle) + 1) / 2.0) * 10
if style == "lines":
draw.line(
(prev_x + line, prev_y + line, x - line, y - line), fill=(r, g, b)
)
else:
line += 1
draw.ellipse(
(x - line, y - line, x + (line * 2), y + (line * 2)), fill=(r, g, b)
)

prev_x = x
prev_y = y

disp.display(img)
disp2.display(ImageOps.invert(img))

0 comments on commit c0dcb1f

Please sign in to comment.