Skip to content

Add Touchscreen Calibrator Example #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 28, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions examples/touchscreen_calibrator_built_in.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# SPDX-FileCopyrightText: 2022 Cedar Grove Maker Studios
# SPDX-License-Identifier: MIT

"""
touch_calibrator_built_in.py 2022-05-27 v2.2

Author(s): JG for Cedar Grove Maker Studios

On-screen touchscreen calibrator for built-in displays.

When the test screen appears, use a stylus to swipe to the four edges
of the visible display area. As the screen is calibrated, the small red
square tracks the stylus tip (REPL_ONLY=False). Minimum and maximum
calibration values will display on the screen and in the REPL. The calibration
tuple can be copied and pasted into the calling code's touchscreen
instantiation statement.

DISPLAY_ROTATION: Display rotation value in degrees. Only values of
None, 0, 90, 180, and 270 degrees are accepted. Defaults to None, the
previous orientation of the display.

REPL_ONLY: If False, calibration values are shown graphically on the screen
and printed to the REPL. If True, the values are only printed to the REPL.
Default value is False.
"""

import time
import board
import displayio
import vectorio
import terminalio
from adafruit_display_text.label import Label
from simpleio import map_range
import adafruit_touchscreen


# Operational parameters:
DISPLAY_ROTATION = 0 # Specify 0, 90, 180, or 270 degrees
REPL_ONLY = False # True to disable graphics

# pylint: disable=too-few-public-methods
class Colors:
"""A collection of colors used for graphic objects."""

BLUE_DK = 0x000060 # Screen fill
RED = 0xFF0000 # Boundary
WHITE = 0xFFFFFF # Text


# Instantiate the built-in display
display = board.DISPLAY

# Check rotation value and update display.
# Always set rotation before instantiating the touchscreen.
if DISPLAY_ROTATION is not None and DISPLAY_ROTATION in (0, 90, 180, 270):
display.rotation = DISPLAY_ROTATION
else:
print("Warning: invalid rotation value -- defaulting to zero")
display.rotation = 0
time.sleep(1)

# Activate the display graphics unless REPL_ONLY=True
if not REPL_ONLY:
display_group = displayio.Group()
display.show(display_group)

# Instantiate touch screen without calibration or display size parameters
if display.rotation == 0:
ts = adafruit_touchscreen.Touchscreen(
board.TOUCH_XL,
board.TOUCH_XR,
board.TOUCH_YD,
board.TOUCH_YU,
# calibration=((5200, 59000), (5250, 59500)),
# size=(board.DISPLAY.width, board.DISPLAY.height),
)

elif display.rotation == 90:
ts = adafruit_touchscreen.Touchscreen(
board.TOUCH_YU,
board.TOUCH_YD,
board.TOUCH_XL,
board.TOUCH_XR,
# calibration=((5250, 59500), (5200, 59000)),
# size=(board.DISPLAY.width, board.DISPLAY.height),
)

elif display.rotation == 180:
ts = adafruit_touchscreen.Touchscreen(
board.TOUCH_XR,
board.TOUCH_XL,
board.TOUCH_YU,
board.TOUCH_YD,
# calibration=((5200, 59000), (5250, 59500)),
# size=(board.DISPLAY.width, board.DISPLAY.height),
)

elif display.rotation == 270:
ts = adafruit_touchscreen.Touchscreen(
board.TOUCH_YD,
board.TOUCH_YU,
board.TOUCH_XR,
board.TOUCH_XL,
# calibration=((5250, 59500), (5200, 59000)),
# size=(board.DISPLAY.width, board.DISPLAY.height),
)
else:
raise ValueError("Rotation value must be 0, 90, 180, or 270")

# Define the graphic objects if REPL_ONLY = False
if not REPL_ONLY:
# Define the text graphic objects
font_0 = terminalio.FONT

coordinates = Label(
font=font_0,
text="calib: ((x_min, x_max), (y_min, y_max))",
color=Colors.WHITE,
)
coordinates.anchor_point = (0.5, 0.5)
coordinates.anchored_position = (
board.DISPLAY.width // 2,
board.DISPLAY.height // 4,
)

display_rotation = Label(
font=font_0,
text="rotation: " + str(display.rotation),
color=Colors.WHITE,
)
display_rotation.anchor_point = (0.5, 0.5)
display_rotation.anchored_position = (
board.DISPLAY.width // 2,
board.DISPLAY.height // 4 - 30,
)

# Define graphic objects for the screen fill, boundary, and touch pen
target_palette = displayio.Palette(1)
target_palette[0] = Colors.BLUE_DK
screen_fill = vectorio.Rectangle(
pixel_shader=target_palette,
x=2,
y=2,
width=board.DISPLAY.width - 4,
height=board.DISPLAY.height - 4,
)

target_palette = displayio.Palette(1)
target_palette[0] = Colors.RED
boundary = vectorio.Rectangle(
pixel_shader=target_palette,
x=0,
y=0,
width=board.DISPLAY.width,
height=board.DISPLAY.height,
)

pen = vectorio.Rectangle(
pixel_shader=target_palette,
x=board.DISPLAY.width // 2,
y=board.DISPLAY.height // 2,
width=10,
height=10,
)

display_group.append(boundary)
display_group.append(screen_fill)
display_group.append(pen)
display_group.append(coordinates)
display_group.append(display_rotation)

# pylint: disable=invalid-name
# Reset x and y values to raw touchscreen mid-point before measurement
x_min = x_max = y_min = y_max = 65535 // 2

print("Touchscreen Calibrator")
print(" Use a stylus to swipe slightly beyond the")
print(" four edges of the visible display area.")
print(" ")
print(f" display rotation: {display.rotation} degrees")
print(" Calibration values follow:")
print(" ")

while True:
time.sleep(0.100)
touch = ts.touch_point # Check for touch
if touch:
# Remember minimum and maximum values for the calibration tuple
x_min = min(x_min, touch[0])
x_max = max(x_max, touch[0])
y_min = min(y_min, touch[1])
y_max = max(y_max, touch[1])

# Show the calibration tuple.
print(f"(({x_min}, {x_max}), ({y_min}, {y_max}))")
if not REPL_ONLY:
pen.x = int(map_range(touch[0], x_min, x_max, 0, board.DISPLAY.width)) - 5
pen.y = int(map_range(touch[1], y_min, y_max, 0, board.DISPLAY.height)) - 5
coordinates.text = f"calib: (({x_min}, {x_max}), ({y_min}, {y_max}))"