Skip to content

Commit 71989b3

Browse files
add touchscreen calibrator example
1 parent d6debff commit 71989b3

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed

examples/touch_calibrator_built_in.py

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# SPDX-FileCopyrightText: 2022 Cedar Grove Maker Studios
2+
# SPDX-License-Identifier: MIT
3+
4+
"""
5+
touch_calibrator_built_in.py 2022-01-21 v2.1
6+
7+
Author(s): JG for Cedar Grove Maker Studios
8+
9+
On-screen touchscreen calibrator for built-in displays.
10+
11+
When the test screen appears, use a stylus to swipe to the four edges
12+
of the visible display area. As the screen is calibrated, the small red
13+
square tracks the stylus tip (REPL_ONLY=False). Minimum and maximum
14+
calibration values will display on the screen and in the REPL. The calibration
15+
tuple can be copied and pasted into the calling code's touchscreen
16+
instantiation statement.
17+
18+
DISPLAY_ROTATION: Display rotation value in degrees. Only values of
19+
None, 0, 90, 180, and 270 degrees are accepted. Defaults to None, the
20+
previous orientation of the display.
21+
22+
REPL_ONLY: If False, calibration values are shown graphically on the screen
23+
and printed to the REPL. If True, the values are only printed to the REPL.
24+
Default value is False.
25+
"""
26+
27+
import time
28+
import board
29+
import displayio
30+
import vectorio
31+
import terminalio
32+
from adafruit_display_text.label import Label
33+
import adafruit_touchscreen
34+
from simpleio import map_range
35+
36+
# Operational parameters:
37+
DISPLAY_ROTATION = 0 # Specify 0, 90, 180, or 270 degrees
38+
REPL_ONLY = False # True to disable graphics
39+
40+
# pylint: disable=too-few-public-methods
41+
class Colors:
42+
"""A collection of colors used for graphic objects."""
43+
44+
BLUE_DK = 0x000060 # Screen fill
45+
RED = 0xFF0000 # Boundary
46+
WHITE = 0xFFFFFF # Text
47+
48+
49+
# Instantiate the built-in display.
50+
display = board.DISPLAY
51+
52+
# Check rotation value and update display.
53+
# Always set rotation before instantiating the touchscreen.
54+
if DISPLAY_ROTATION is not None and DISPLAY_ROTATION in (0, 90, 180, 270):
55+
display.rotation = DISPLAY_ROTATION
56+
else:
57+
print("Warning: invalid rotation value -- defalting to zero")
58+
display.rotation = 0
59+
time.sleep(1)
60+
61+
# Activate the display graphics unless REPL_ONLY=True.
62+
if not REPL_ONLY:
63+
display_group = displayio.Group()
64+
display.show(display_group)
65+
66+
# Instantiate touch screen without calibration or display size parameters
67+
if display.rotation == 0:
68+
ts = adafruit_touchscreen.Touchscreen(
69+
board.TOUCH_XL,
70+
board.TOUCH_XR,
71+
board.TOUCH_YD,
72+
board.TOUCH_YU,
73+
# calibration=((5200, 59000), (5250, 59500)),
74+
# size=(board.DISPLAY.width, board.DISPLAY.height),
75+
)
76+
77+
elif display.rotation == 90:
78+
ts = adafruit_touchscreen.Touchscreen(
79+
board.TOUCH_YU,
80+
board.TOUCH_YD,
81+
board.TOUCH_XL,
82+
board.TOUCH_XR,
83+
# calibration=((5250, 59500), (5200, 59000)),
84+
# size=(board.DISPLAY.width, board.DISPLAY.height),
85+
)
86+
87+
elif display.rotation == 180:
88+
ts = adafruit_touchscreen.Touchscreen(
89+
board.TOUCH_XR,
90+
board.TOUCH_XL,
91+
board.TOUCH_YU,
92+
board.TOUCH_YD,
93+
# calibration=((5200, 59000), (5250, 59500)),
94+
# size=(board.DISPLAY.width, board.DISPLAY.height),
95+
)
96+
97+
elif display.rotation == 270:
98+
ts = adafruit_touchscreen.Touchscreen(
99+
board.TOUCH_YD,
100+
board.TOUCH_YU,
101+
board.TOUCH_XR,
102+
board.TOUCH_XL,
103+
# calibration=((5250, 59500), (5200, 59000)),
104+
# size=(board.DISPLAY.width, board.DISPLAY.height),
105+
)
106+
else:
107+
raise ValueError("Rotation value must be 0, 90, 180, or 270")
108+
109+
# Define the graphic objects if REPL_ONLY = False.
110+
if not REPL_ONLY:
111+
# Define the text graphic objects
112+
font_0 = terminalio.FONT
113+
114+
coordinates = Label(
115+
font=font_0,
116+
text="calib: ((x_min, x_max), (y_min, y_max))",
117+
color=Colors.WHITE,
118+
)
119+
coordinates.anchor_point = (0.5, 0.5)
120+
coordinates.anchored_position = (
121+
board.DISPLAY.width // 2,
122+
board.DISPLAY.height // 4,
123+
)
124+
125+
display_rotation = Label(
126+
font=font_0,
127+
text="rotation: " + str(display.rotation),
128+
color=Colors.WHITE,
129+
)
130+
display_rotation.anchor_point = (0.5, 0.5)
131+
display_rotation.anchored_position = (
132+
board.DISPLAY.width // 2,
133+
board.DISPLAY.height // 4 - 30,
134+
)
135+
136+
# Define graphic objects for the screen fill, boundary, and touch pen.
137+
target_palette = displayio.Palette(1)
138+
target_palette[0] = Colors.BLUE_DK
139+
screen_fill = vectorio.Rectangle(
140+
pixel_shader=target_palette,
141+
x=2,
142+
y=2,
143+
width=board.DISPLAY.width - 4,
144+
height=board.DISPLAY.height - 4,
145+
)
146+
147+
target_palette = displayio.Palette(1)
148+
target_palette[0] = Colors.RED
149+
boundary = vectorio.Rectangle(
150+
pixel_shader=target_palette,
151+
x=0,
152+
y=0,
153+
width=board.DISPLAY.width,
154+
height=board.DISPLAY.height,
155+
)
156+
157+
pen = vectorio.Rectangle(
158+
pixel_shader=target_palette,
159+
x=board.DISPLAY.width // 2,
160+
y=board.DISPLAY.height // 2,
161+
width=10,
162+
height=10,
163+
)
164+
165+
display_group.append(boundary)
166+
display_group.append(screen_fill)
167+
display_group.append(pen)
168+
display_group.append(coordinates)
169+
display_group.append(display_rotation)
170+
171+
# pylint: disable=invalid-name
172+
# Reset x and y values to raw touchscreen mid-point before measurement.
173+
x_min = x_max = y_min = y_max = 65535 // 2
174+
175+
print("Touchscreen Calibrator")
176+
print(" Use a stylus to swipe slightly beyond the")
177+
print(" four edges of the visible display area.")
178+
print(" ")
179+
print(f" display rotation: {display.rotation} degrees")
180+
print(" Calibration values follow:")
181+
print(" ")
182+
183+
while True:
184+
time.sleep(0.100)
185+
touch = ts.touch_point # Check for touch
186+
if touch:
187+
if not REPL_ONLY:
188+
pen.x = int(map_range(touch[0], x_min, x_max, 0, board.DISPLAY.width)) - 5
189+
pen.y = int(map_range(touch[1], y_min, y_max, 0, board.DISPLAY.height)) - 5
190+
191+
# Remember minimum and maximum values for the calibration tuple.
192+
x_min = min(x_min, touch[0])
193+
x_max = max(x_max, touch[0])
194+
y_min = min(y_min, touch[1])
195+
y_max = max(y_max, touch[1])
196+
197+
# Show the calibration tuple.
198+
print(f"(({x_min}, {x_max}), ({y_min}, {y_max}))")
199+
if not REPL_ONLY:
200+
coordinates.text = f"calib: (({x_min}, {x_max}), ({y_min}, {y_max}))"

0 commit comments

Comments
 (0)