Simple test
Ensure your device works with this simple test.
examples/asyncio_simpletest.py
1# SPDX-FileCopyrightText: 2022 Dan Halbert for Adafruit Industries
2#
3# SPDX-License-Identifier: MIT
4
5# -----[Example for one led]-----------------------------
6
7import asyncio
8
9import board
10import digitalio
11
12
13async def blink(pin, interval, count): # Don't forget the async!
14 with digitalio.DigitalInOut(pin) as led:
15 led.switch_to_output(value=False)
16 for _ in range(count):
17 led.value = True
18 await asyncio.sleep(interval) # Don't forget the await!
19 led.value = False
20 await asyncio.sleep(interval) # Don't forget the await!
21
22
23async def main(): # Don't forget the async!
24 led_task = asyncio.create_task(blink(board.D1, 0.25, 10))
25 await asyncio.gather(led_task) # Don't forget the await!
26 print("done")
27
28
29asyncio.run(main())
30
31
32# -----[Example for two leds]-------------------------------
33
34# Import modules as above
35
36
37async def blink(pin, interval, count):
38 with digitalio.DigitalInOut(pin) as led:
39 led.switch_to_output(value=False)
40 for _ in range(count):
41 led.value = True
42 await asyncio.sleep(interval) # Don't forget the "await"!
43 led.value = False
44 await asyncio.sleep(interval) # Don't forget the "await"!
45
46
47async def main():
48 led1_task = asyncio.create_task(blink(board.D1, 0.25, 10))
49 led2_task = asyncio.create_task(blink(board.D2, 0.1, 20))
50
51 await asyncio.gather(led1_task, led2_task) # Don't forget "await"!
52 print("done")
53
54
55asyncio.run(main())
Displayio Button Example
Illustrates how to use Display_Buttons and blinking vectorio.Circles with asyncio
examples/asyncio_displayio_button.py
1# SPDX-FileCopyrightText: 2022 Tim Cocks for Adafruit Industries
2#
3# SPDX-License-Identifier: MIT
4"""
5Example that illustrates how to use Displayio Buttons to modify
6some blinking circles. One button inverts colors, the others change
7the interval length of the blink for one of the circles.
8"""
9
10import asyncio
11
12import adafruit_touchscreen
13import board
14import displayio
15import terminalio
16import vectorio
17from adafruit_button import Button
18
19# use built-in display
20display = board.DISPLAY
21
22# explicitly set the display to default orientation in-case it was changed
23display.rotation = 0
24
25# --| Button Config |-------------------------------------------------
26# invert color Button
27BUTTON_1_X = 10
28BUTTON_1_Y = 80
29BUTTON_1_LABEL = "Invert Color"
30
31# slower interval Button
32BUTTON_2_X = 200
33BUTTON_2_Y = 160
34BUTTON_2_LABEL = "Slower"
35
36# faster interval Button
37BUTTON_3_X = 200
38BUTTON_3_Y = 80
39BUTTON_3_LABEL = "Faster"
40
41# shared button configurations
42BUTTON_WIDTH = 100
43BUTTON_HEIGHT = 50
44BUTTON_STYLE = Button.ROUNDRECT
45BUTTON_FILL_COLOR = 0x00FFFF
46BUTTON_OUTLINE_COLOR = 0xFF00FF
47BUTTON_LABEL_COLOR = 0x000000
48# --| Button Config |-------------------------------------------------
49
50# Setup touchscreen (PyPortal)
51ts = adafruit_touchscreen.Touchscreen(
52 board.TOUCH_XL,
53 board.TOUCH_XR,
54 board.TOUCH_YD,
55 board.TOUCH_YU,
56 calibration=((5200, 59000), (5800, 57000)),
57 size=(display.width, display.height),
58)
59
60# initialize color button
61invert_color_btn = Button(
62 x=BUTTON_1_X,
63 y=BUTTON_1_Y,
64 width=BUTTON_WIDTH,
65 height=BUTTON_HEIGHT,
66 style=BUTTON_STYLE,
67 fill_color=BUTTON_FILL_COLOR,
68 outline_color=BUTTON_OUTLINE_COLOR,
69 label=BUTTON_1_LABEL,
70 label_font=terminalio.FONT,
71 label_color=BUTTON_LABEL_COLOR,
72)
73
74# initialize interval slower button
75interval_slower_btn = Button(
76 x=BUTTON_2_X,
77 y=BUTTON_2_Y,
78 width=BUTTON_WIDTH,
79 height=BUTTON_HEIGHT,
80 style=BUTTON_STYLE,
81 fill_color=BUTTON_FILL_COLOR,
82 outline_color=BUTTON_OUTLINE_COLOR,
83 label=BUTTON_2_LABEL,
84 label_font=terminalio.FONT,
85 label_color=BUTTON_LABEL_COLOR,
86)
87
88# initialize interval faster button
89interval_faster_btn = Button(
90 x=BUTTON_3_X,
91 y=BUTTON_3_Y,
92 width=BUTTON_WIDTH,
93 height=BUTTON_HEIGHT,
94 style=BUTTON_STYLE,
95 fill_color=BUTTON_FILL_COLOR,
96 outline_color=BUTTON_OUTLINE_COLOR,
97 label=BUTTON_3_LABEL,
98 label_font=terminalio.FONT,
99 label_color=BUTTON_LABEL_COLOR,
100)
101
102
103# Button state data object. Will hold either true of false whether button is currently pressed
104class ButtonState:
105 def __init__(self, initial_state):
106 self.state = initial_state
107
108
109# Interval length data object. Holds the amount of time in ms the interval should last for
110class Interval:
111 def __init__(self, initial_value):
112 self.value = initial_value
113
114
115# main group to show things on the display
116main_group = displayio.Group()
117
118# Initialize first circle
119palette_1 = displayio.Palette(2)
120palette_1[0] = 0x125690
121palette_1[1] = 0x125690
122circle_1 = vectorio.Circle(pixel_shader=palette_1, radius=15, x=20, y=20)
123
124# Initialize second circle
125palette_2 = displayio.Palette(2)
126palette_2[0] = 0x12FF30
127palette_2[1] = 0x12FF30
128circle_2 = vectorio.Circle(pixel_shader=palette_2, radius=15, x=60, y=20)
129
130# add everything to the group, so it gets displayed
131main_group.append(circle_1)
132main_group.append(circle_2)
133main_group.append(invert_color_btn)
134main_group.append(interval_slower_btn)
135main_group.append(interval_faster_btn)
136
137
138async def blink(palette, interval, count, button_state): # Don't forget the async!
139 """
140 blink coroutine. Hides and shows a vectorio shape by
141 using make_transparent() and make_opaque() on it's palette.
142
143 :param displayio.Palette palette: The palette to change colors on for blinking
144 :param Interval interval: The Interval data object containing the interval length to use
145 :param int count: The number of times to repeat the blink. -1 for indefinite loop
146 :param ButtonState button_state: The ButtonState data object for the invert color button
147 """
148 while count < 0 or count > 0:
149 # if the color button is pressed
150 if button_state.state:
151 # if the color is still on default
152 if palette[0] == palette[1]:
153 # invert the color by subtracting from white
154 palette[0] = 0xFFFFFF - palette[0]
155
156 # if the color button is not pressed
157 else:
158 # set the color back to default
159 palette[0] = palette[1]
160
161 # hide the circle
162 palette.make_opaque(0)
163 # wait interval length
164 await asyncio.sleep(interval.value / 1000) # Don't forget the await!
165
166 # show the circle
167 palette.make_transparent(0)
168 # wait interval length
169 await asyncio.sleep(interval.value / 1000) # Don't forget the await!
170
171 # decrement count if it's positive
172 if count > 0:
173 count -= 1
174
175
176def handle_color_button(touch_event, color_button, button_state):
177 """
178 Check if the color button is pressed, and updates
179 the ButtonState data object as appropriate
180
181 :param touch_event: The touch point object from touchscreen
182 :param Button color_button: The button to check for presses on
183 :param ButtonState button_state: ButtonState data object to set
184 the current value into
185 """
186
187 # if there is a touch event
188 if touch_event:
189 # if the color button is being touched
190 if color_button.contains(touch_event):
191 # set selected to change button color
192 color_button.selected = True
193 # set button_state so other coroutines can access it
194 button_state.state = True
195
196 # the color button is not being touched
197 else:
198 # set selected to change button color back to default
199 color_button.selected = False # if touch is dragged outside of button
200 # set button_state so other coroutines can access it.
201 button_state.state = False
202
203 # there are no touch events
204 elif color_button.selected:
205 # set selected back to false to change button back to default color
206 color_button.selected = False
207 # set button_state so other coroutines can access it
208 button_state.state = False
209
210
211def handle_interval_buttons(touch_event, button_slower, button_faster, interval):
212 """
213 Will check for presses on
214 the faster and slower buttons and updated the data in the
215 Interval data object as appropriate
216
217 :param touch_event: Touch point object from touchscreen
218 :param Button button_slower: The slower button object
219 :param Button button_faster: The faster button object
220 :param Interval interval: The Interval data object to store state
221 """
222 # if there are any touch events
223 if touch_event:
224 # if the slower button is being touched
225 if button_slower.contains(touch_event):
226 # if it just became pressed. i.e. was not pressed last frame
227 if not button_slower.selected:
228 # set selected to change the button color
229 button_slower.selected = True
230
231 # increment the interval length and store it on the data object
232 interval.value += 100
233 print(f"new interval val: {interval.value}")
234
235 # if the slower button is not being touched
236 else:
237 # set selected to put the slower button back to default color
238 button_slower.selected = False
239
240 # if the faster button is being touched
241 if button_faster.contains(touch_event):
242 # if it just became pressed. i.e. was not pressed last frame
243 if not button_faster.selected:
244 # set selected to change the button color
245 button_faster.selected = True
246 # if the interval is large enough to decrement
247 if interval.value >= 100:
248 # decrement interval value and store it on the data object
249 interval.value -= 100
250 print(f"new interval val: {interval.value}")
251
252 # if the faster button is not being touched
253 else:
254 # set selected back to false to change color back to default
255 button_faster.selected = False
256
257 # there are no touch events
258 else:
259 # if slower button is the pressed color
260 if button_slower.selected:
261 # set it back to default color
262 button_slower.selected = False
263
264 # if the faster button is pressed color
265 if button_faster.selected:
266 # set it back to default color
267 button_faster.selected = False
268
269
270async def monitor_buttons(button_slower, button_faster, color_button, interval, button_state):
271 """
272 monitor_buttons coroutine.
273
274 :param Button button_slower: The slower button object
275 :param Button button_faster: The faster button object
276 :param Button color_button: The invert color button object
277 :param Interval interval: The Interval data object to store state
278 :param ButtonState button_state: The ButtonState data object to
279 store color button state
280 """
281 while True:
282 # get current touch data from overlay
283 p = ts.touch_point
284
285 # handle touch event data
286 handle_color_button(p, color_button, button_state)
287 handle_interval_buttons(p, button_slower, button_faster, interval)
288
289 # allow other tasks to do work
290 await asyncio.sleep(0)
291
292
293# main coroutine
294async def main(): # Don't forget the async!
295 # create data objects
296 color_btn_state = ButtonState(False)
297 interval_1 = Interval(550)
298 interval_2 = Interval(350)
299
300 # create circle blink tasks
301 circle_1_task = asyncio.create_task(blink(palette_1, interval_1, -1, color_btn_state))
302 circle_2_task = asyncio.create_task(blink(palette_2, interval_2, 20, color_btn_state))
303
304 # create buttons task
305 button_task = asyncio.create_task(
306 monitor_buttons(
307 interval_slower_btn,
308 interval_faster_btn,
309 invert_color_btn,
310 interval_1,
311 color_btn_state,
312 )
313 )
314
315 # start all of the tasks
316 await asyncio.gather(circle_1_task, circle_2_task, button_task) # Don't forget the await!
317
318
319# show main_group so it's visible on the display
320display.root_group = main_group
321
322# start the main coroutine
323asyncio.run(main())