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())