Skip to content

Latest commit

 

History

History
834 lines (581 loc) · 31.9 KB

File metadata and controls

834 lines (581 loc) · 31.9 KB

十五、Adafruit HalloWing 微控制器的编程

在本章中,我们将创建一个讲笑话的机器。我们将使用 Adafruit HalloWing M0 Express 板,该板配有全彩色 TFT 显示屏和电容式触摸传感器。每次按下触摸按钮,就会出现一个新的笑话谜语。您可以尝试找出谜语的答案,当您准备好时,触摸按钮以显示谜语的答案。再次按下触摸按钮可随机选择一个新谜语并开始另一个游戏。

本章将是一个有用的信息来源,并帮助您构建项目,使您能够利用具有足够高分辨率的全彩屏幕的强大功能来显示多行文本和全彩图形图像。

本章将介绍以下配方:

  • 发现 I2C 设备
  • 使用 I2C 从加速计读取数据
  • 用加速度计检测电路板翻转
  • 控制屏幕亮度
  • 显示位图图像
  • 列出所有图像文件
  • 创造一个讲笑话的机器

Adafruit HalloWing M0 快车

Adafruit HalloWing 是一款内置 1.44 英寸 128 x 128 全彩 TFT 显示屏的微控制器。显示图像的软件完全支持显示全彩位图图像文件。设备上有 8 MB 的存储空间,这为您提供了大量存储和显示图像的空间。该电路板还配备了一个 3 轴加速计、光传感器和 4 个电容式触摸板。以下屏幕截图显示了显示位图图像的 TFT 屏幕:

该板可由便携式电源供电。它支持可充电锂离子聚合物电池和 USB 便携式电源组。

在哪里买

Adafruit Hallow M0 快板可直接从 Adafruit(购买 https://www.adafruit.com/product/3900 )。

技术要求

本章的代码文件可在本书 GitHub 存储库的Chapter15文件夹中找到,位于https://github.com/PacktPublishing/MicroPython-Cookbook

本章使用 Adafruit HalloWing M0 Express 板,加载了 CircuitPython 固件。CircuitPython 版本 4.0.0-rc.1 用于本章中的所有配方。

You may download the firmware image from https://circuitpython.org/board/hallowing_m0_express/.

本章中的许多食谱都需要将一组位图图像传输到 Adafruit HalloWing 设备。它们都可以从本书 GitHub 存储库的Chapter15文件夹下载。它们应该与您的main.py文件一起保存在顶级文件夹中。

发现 I2C 设备

本食谱将向您展示如何使用i2c对象扫描连接到总线的 I2C 设备。I2C 协议支持将多个设备连接到单个 I2C 连接。连接到设备的第一步是扫描并列出所有检测到的设备。此配方将帮助您对 I2C 设备进行故障排除,以确认它已连接,并且可以在扫描中找到。它还可以帮助您构建能够自动扫描和检测多个设备的 Python 脚本。

准备

您需要访问 Adafruit HalloWing 板上的 REPL 才能运行此配方中提供的代码。

怎么做。。。

按照以下步骤学习如何发现 I2C 设备:

  1. 在 REPL 中运行以下代码行:
>>> import board
>>> import busio
  1. 所需的库将已导入。R 运行以下代码行以创建将用于扫描的i2c对象:
>>> i2c = busio.I2C(board.SCL, board.SDA)
  1. 以下代码行将保持循环,直到 I2C 总线上获得锁:
>>> while not i2c.try_lock():
...     print('getting lock...')
...     
...     
... 
>>> 
  1. 以下代码块执行扫描并列出所有检测到的设备:
>>> i2c.scan()
[24]
  1. 我们可以再次执行扫描,并将返回的设备地址转换为十六进制格式:
>>> [hex(x) for x in i2c.scan()]
['0x18']
  1. 以下代码应放入main.py文件中:
import board
import busio

def main():
    i2c = busio.I2C(board.SCL, board.SDA)
    while not i2c.try_lock():
        print('getting lock...')
    devices = [hex(x) for x in i2c.scan()]
    print('devices found:', devices)

main()

执行此脚本时,它将打印出所有查找到的设备的地址。

它是如何工作的。。。

主功能设置i2c对象。然后重复调用try_lock方法,直到获得锁为止。在 I2C 总线上执行扫描时需要此锁。然后调用scan方法,返回设备地址列表。然后将每个地址转换为十六进制符号,并保存为设备变量中的字符串列表。最后,该变量的内容将输出一条消息,指示这是在总线上发现的设备列表。

还有更多。。。

某些 I2C 操作(如扫描)需要锁定。如果您在没有先获取锁的情况下尝试执行扫描,则会出现运行时错误,指示此函数需要锁。在下一个配方中,我们将看到还有其他不需要锁的操作。I2C 的地址经常使用十六进制表示法,这就是为什么我们将值从整数转换为十六进制值的原因。

Adafruit HalloWing M0 Express 板配有一个 I2C 设备和一个加速计,加速计的地址应为0x18。我们的扫描证实了这一点。如果您不确定设备的特定地址值,可以使用扫描方法检测这些值。

另见

以下是有关此配方的一些参考资料:

使用 I2C 从加速计读取数据

此配方将向您展示如何使用 I2C 协议连接到车载加速计。一旦我们有了 I2C 对象,我们将使用 Pythonadafruit_lis3dh库来创建LIS3DH_I2C对象。该对象将允许我们从加速计读取实时传感器数据。无论何时,只要您想要创建一个使用董事会方向创建交互体验的项目,此食谱都将帮助您。例如,您可以创建一个项目,通过更改当前显示的图像来对电路板的晃动做出反应。

准备

您需要访问 Adafruit HalloWing 设备上的 REPL 才能运行此配方中提供的代码。

怎么做。。。

按照以下步骤学习如何使用 I2C 从加速计读取数据:

  1. 在 REPL 中执行以下代码块:
>>> from adafruit_lis3dh import LIS3DH_I2C
>>> import board
>>> import busio
>>> import time
>>> 
>>> ACCEL_ADDRESS = 0x18
  1. 现在已导入所需的库,加速计地址已在ACCEL_ADDRESS常量中定义。运行以下代码块创建i2c对象,并使用该对象创建LIS3DH_I2C对象:
>>> i2c = busio.I2C(board.SCL, board.SDA)
>>> accel = LIS3DH_I2C(i2c, address=ACCEL_ADDRESS)
  1. 以下代码块将获取加速计方向数据并显示其值:
>>> accel.acceleration
acceleration(x=0.143678, y=-0.0287355, z=-9.48272)
  1. 我们还可以使用以下代码块访问特定信息,例如x轴方向数据:
>>> accel.acceleration.x
0.124521
  1. 以下回路用于每 0.1 秒打印一次实时加速计传感器数据:
>>> while True:
...     print(accel.acceleration)
...     time.sleep(0.1)
...     
...     
... 
acceleration(x=0.162835, y=-0.00957851, z=-9.47314)
acceleration(x=0.162835, y=-0.0478925, z=-9.52104)
acceleration(x=0.0957851, y=-0.057471, z=-9.30073)
acceleration(x=0.172413, y=-0.00957851, z=-9.51146)
acceleration(x=0.153256, y=-0.0478925, z=-9.48272)
acceleration(x=0.153256, y=-0.057471, z=-9.53062)
acceleration(x=0.162835, y=-0.057471, z=-9.53062)
  1. 以下代码应放入main.py文件中:
from adafruit_lis3dh import LIS3DH_I2C
import board
import busio
import time

ACCEL_ADDRESS = 0x18

def main():
    i2c = busio.I2C(board.SCL, board.SDA)
    accel = LIS3DH_I2C(i2c, address=ACCEL_ADDRESS)
    while True:
        print(accel.acceleration)
        time.sleep(0.1)

main()

执行此脚本时,它将每隔 0.1 秒从加速计打印传感器数据。

它是如何工作的。。。

ACCEL_ADDRESS常数包含 Adafruit HalloWing M0 Express 板上加速计的地址。一旦我们创建了一个i2c对象,我们就用它和ACCEL_ADDRESS来创建一个LIS3DH_I2C对象,我们将把它保存在一个名为accel的变量中。启动一个无限循环,在每次迭代时从加速计读取传感器数据并打印出来。然后循环在开始下一次迭代之前等待 0.1 秒的延迟。

还有更多。。。

Adafruit HalloWing 设备上使用的加速计的名称称为 LIS3DH,这就是为什么知道如何与该设备通话的 Python 库称为adafruit_lis3dh。该传感器可用于检测电路板的方向和加速度。在下一个配方中,我们将使用此方向数据来检测电路板何时翻转。

另见

以下是有关此配方的一些参考资料:

用加速度计检测电路板翻转

此配方将向您展示如何创建一个检测电路板翻转时间的函数。为了实现这一点,我们将使用从加速计获取的方向数据。我们将重点关注z轴数据,因为这将指示电路板是朝上还是朝下。无论何时,只要您正在创建一个项目,并且希望找到一种与项目交互的更具创造性的方式,而不仅仅是按下按钮,本食谱中介绍的方法都会对您有用。当有人发现他们所要做的就是翻转你的棋盘与之互动时,这可以创造一个有趣的互动水平。

准备

您需要访问 Adafruit HalloWing 设备上的 REPL 才能运行此配方中提供的代码。

怎么做。。。

按照以下步骤学习如何使用加速计检测电路板翻转:

  1. 使用 REPL 运行以下代码行:
>>> from adafruit_lis3dh import LIS3DH_I2C
>>> import board
>>> import busio
>>> import time
>>> 
>>> ACCEL_ADDRESS = 0x18
  1. 所需的库已导入并不断定义。运行以下代码块来创建i2cLIS3DH_I2C对象:
>>> i2c = busio.I2C(board.SCL, board.SDA)
>>> accel = LIS3DH_I2C(i2c, address=ACCEL_ADDRESS)
  1. 我们现在可以检查z轴方向数据:
>>> accel.acceleration.z
-9.43483
  1. 翻转电路板,使其显示面朝下,然后运行以下代码块:
>>> accel.acceleration.z
9.50188
  1. z轴的方向值是正数还是负数,取决于电路板是正面朝上还是正面朝下。执行以下代码块以计算此值:
>>> face = 'up' if accel.acceleration.z < 0 else 'down'
>>> face
'up'
  1. 在正面朝下和正面朝上翻转电路板时,运行以下代码块:
>>> while True:
...     face = 'up' if accel.acceleration.z < 0 else 'down'
...     print('board is face', face)
...     time.sleep(0.1)
...     
...     
... 
board is face up
board is face up
board is face up
board is face down
board is face down
board is face up
board is face up
board is face up
  1. 以下代码应放入main.py文件中:
from adafruit_lis3dh import LIS3DH_I2C
import board
import busio
import time

ACCEL_ADDRESS = 0x18

def main():
    i2c = busio.I2C(board.SCL, board.SDA)
    accel = LIS3DH_I2C(i2c, address=ACCEL_ADDRESS)
    while True:
        face = 'up' if accel.acceleration.z < 0 else 'down'
        print('board is face', face)
        time.sleep(0.1)

main()

执行此脚本时,它将每隔 0.1 秒打印一次电路板是朝上还是朝下。

它是如何工作的。。。

一旦设置了i2caccel变量,我们就可以开始从加速计访问方向数据。板朝上时,z值为负数,板朝下时,z值为正数。我们可以使用这条信息来计算电路板是朝上还是朝下。无限循环启动,变量面保存有updown值,具体取决于电路板的当前方向。然后在循环等待 0.1 秒延迟后再开始下一次迭代时打印此信息。

还有更多。。。

该配方向您展示了如何使用来自加速度计的一条信息来检测电路板物理方向的变化。一旦我们检测到这种变化,我们就可以让脚本改变它的输出,例如,只要电路板的面值发生变化。加速计也足够精确,可以提供电路板指向z轴的角度。我们可以使用这些信息来更改应用程序的行为,具体取决于电路板在某个方向上的倾斜程度。

另见

以下是有关此配方的一些参考资料:

控制屏幕亮度

本配方将向您展示如何控制 Adafruit HalloWing 设备附带的 TFT 显示屏的亮度水平。通过提供介于 0 和 1 之间的分数值,可以将亮度设置为最大级别或更低级别。亮度设置也可用于通过将亮度级别设置为 0 来关闭显示器。如果您不想一直打开屏幕,而是想打开和关闭屏幕,则此方法对您非常有用。当您想要将背光的亮度级别调整到较低级别以降低功耗时,它也很有用。

准备

您需要访问 Adafruit HalloWing 设备上的 REPL 才能运行此配方中提供的代码。

怎么做。。。

按照以下步骤学习如何控制 Adafruit HalloWing 设备的屏幕亮度:

  1. 在 REPL 中运行以下代码行:
>>> import board
>>> import time
  1. 已导入所需的库。您可以运行以下代码块将亮度级别设置为 50%:
>>> board.DISPLAY.brightness = 0.5
  1. 以下代码块将通过将亮度设置为 0%来打开显示器:
>>> board.DISPLAY.brightness = 0
  1. 现在,我们可以使用以下代码块将亮度设置为最大级别:
>>> board.DISPLAY.brightness = 1.0
  1. 以下功能将在 11 次迭代中将亮度从最低级别提升到最高级别:
>>> def fade_in():
...     for i in range(0, 11):
...         brightness = i / 10
...         print('brightness:', brightness)
...         board.DISPLAY.brightness = brightness
...         time.sleep(0.1)
...         
...         
... 
>>> 
  1. 运行以下代码块。您应该看到显示屏逐渐变暗,直至达到最大亮度:
>>> fade_in()
brightness: 0.0
brightness: 0.1
brightness: 0.2
brightness: 0.3
brightness: 0.4
brightness: 0.5
brightness: 0.6
brightness: 0.7
brightness: 0.8
brightness: 0.9
brightness: 1.0
>>> 
  1. 以下代码应放入main.py文件中:
import board
import time

def fade_in():
    for i in range(0, 11):
        brightness = i / 10
        print('brightness:', brightness)
        board.DISPLAY.brightness = brightness
        time.sleep(0.1)

def main():
    while True:
        fade_in()

main()

执行此脚本时,它将使屏幕从黑色变为全亮度,每次变暗之间有 0.1 秒的延迟。

它是如何工作的。。。

main 函数启动一个无限循环,该循环反复调用fade_in函数。每次调用fade_in函数都会启动一个for循环,循环 11 个亮度值。这些值各不相同,从关闭显示屏到将显示屏设置为最大亮度。为每次迭代计算亮度级别,并将其存储在亮度变量中。打印该值,然后将其应用于DISPLAY对象上的亮度属性。然后应用 0.1 秒的睡眠,然后再应用下一次循环中的淡入淡出。

还有更多。。。

此配方演示了设置显示器亮度水平的容易程度。它还向您展示了如何在 Python 中实现屏幕效果,例如淡入淡出屏幕。当您希望通过关闭显示器的背光来关闭显示器时,“亮度”属性特别有用。您可以创建一个电池驱动的设备,可以使用此技术优化功耗。

另见

以下是有关此配方的一些参考资料:

显示位图图像

此配方将向您展示如何创建一个函数,该函数接收位图图像的路径,获取该图像,并将其显示在 HalloWing 屏幕上。有许多不同的对象和选项可用于操作屏幕内容。我们将不得不与许多不同的对象交互,即使我们只想显示一幅图像。此配方可让您深入了解在电路板屏幕上渲染图像所涉及的内容。如果您在需要显示不同图像的项目中使用 HalloWing 设备,并且希望以一种简单的方式更改当前显示的图像,则此方法非常有用。

准备

您需要访问 Adafruit HalloWing 设备上的 REPL 才能运行此配方中提供的代码。

怎么做。。。

按照以下步骤学习如何在 HalloWing 设备的屏幕上显示位图图像:

  1. 在 REPL 中执行以下代码块:
>>> import board
>>> from displayio import OnDiskBitmap, ColorConverter, TileGrid, Group
  1. displayio模块中的必要对象现已导入。运行以下代码块以打开二进制流中的文件对象:
>>> path = 'joke_01_question.bmp'
>>> f = open(path, 'rb')
  1. 我们将使用此文件对象创建位图对象,然后准备pixel_shader对象:
>>> bitmap = OnDiskBitmap(f)
>>> pixel_shader = ColorConverter()
  1. 然后将这两个对象用作创建名为spriteTileGrid对象的参数:
sprite = TileGrid(bitmap, pixel_shader=pixel_shader)
  1. 下面的代码块创建了一个 group 对象,并将sprite附加到该对象上:
>>> group = Group()
>>> group.append(sprite)
  1. 我们可以使用以下代码块在显示屏上显示该组,并调用wait_for_frame使代码块等待显示屏完全更新。现在,我们将关闭文件对象,因为它不再需要:
>>> board.DISPLAY.show(group)
>>> board.DISPLAY.wait_for_frame()
>>> f.close()
  1. 运行以下代码块来定义show_image函数,并调用它在显示器上显示不同的图像:
>>> def show_image(path):
...     with open(path, 'rb') as f:
...         bitmap = OnDiskBitmap(f)
...         pixel_shader = ColorConverter()
...         sprite = TileGrid(bitmap, pixel_shader=pixel_shader)
...         group = Group()
...         group.append(sprite)
...         board.DISPLAY.show(group)
...         board.DISPLAY.wait_for_frame()
...         
...         
... 
>>> show_image('joke_01_response.bmp')
>>> 
  1. 以下代码应放入main.py文件中:
import board
from displayio import OnDiskBitmap, ColorConverter, TileGrid, Group

IMAGES = ['joke_01_question.bmp', 'joke_01_response.bmp']

def show_image(path):
    with open(path, 'rb') as f:
        bitmap = OnDiskBitmap(f)
        pixel_shader = ColorConverter()
        sprite = TileGrid(bitmap, pixel_shader=pixel_shader)
        group = Group()
        group.append(sprite)
        board.DISPLAY.show(group)
        board.DISPLAY.wait_for_frame()

def main():
    while True:
        for image in IMAGES:
            show_image(image)

main()

执行此脚本时,它将重复更改两个不同位图之间显示的图像。

它是如何工作的。。。

此配方中的show_image功能完成了在屏幕上显示位图的所有繁重工作。它接收一个参数,即位图文件的路径。此文件打开读取,然后用于创建名为位图的OnDiskBitmap对象。

ColorConverter对象用于创建pixel_shader变量。创建了一个TileGrid对象,需要显示位图以及将使用的像素着色器。提供了这两个参数,新的TileGrid对象保存在 sprite 变量中。sprite 变量不能直接赋给DISPLAY对象,因此我们必须创建一个Group对象并将 sprite 附加到它。

现在我们可以调用DISPLAY对象上的 show 方法来显示group变量。调用wait_for_frame方法以确保图像在继续之前完全显示在屏幕上。主函数启动一个无限循环,反复调用show_image以持续更改当前显示的图像。

还有更多。。。

在 HalloWing 设备上显示位图图像需要使用许多不同类型的对象。部分原因是每个对象在屏幕上显示图像的方式方面提供了广泛的灵活性。例如,您可以控制图像的xy坐标,或者使用其他不来自文件的位图对象。

显示器可以显示分辨率高达 128 x 128 的图像,并以 24 位像素 BMP 文件格式保存。您可以使用开源 GIMP 图像编辑器来创建这些图像。

在 GIMP 应用程序中创建新图像时,应设置正确的分辨率,如以下屏幕截图所示:

准备好保存图像后,请使用“文件”菜单中的“导出”功能,并将图像保存为 BMP 文件格式。执行此操作时,请确保选择了正确的每像素位设置,如以下屏幕截图所示:

重要的是要知道,您也可以使用分辨率较小的图像,并且这些图像将自动检测并正确显示在屏幕上。较小的图像也会更快地显示在屏幕上。

另见

以下是有关此配方的一些参考资料:

列出所有图像文件

此配方将向您展示如何列出特定目录中的所有图像文件。在笑话讲述机中,我们将每个笑话问题和回答创建为一对图像。此配方将允许您在电路板上列出所有位图图像。然后,我们将扩展此功能以进一步过滤列表,并将笑话问题的所有位图图像放在手边。此配方在您创建的任何项目中都很有用,您可以在其中检索要在项目中显示或播放的图像或音频文件列表。

准备

您需要访问 Adafruit HalloWing 设备上的 REPL 才能运行此配方中提供的代码。

怎么做。。。

按照以下步骤学习如何列出图像文件:

  1. 使用 REPL 运行以下代码行:
>>> import os
>>> paths = sorted(os.listdir())
>>> paths
['.Trashes', '.fseventsd', '.metadata_never_index', 'boot_out.txt', 'joke_01_question.bmp', 'joke_01_response.bmp', 'joke_02_question.bmp', 'joke_02_response.bmp', 'joke_03_question.bmp', 'joke_03_response.bmp', 'joke_04_question.bmp', 'joke_04_response.bmp', 'main.py']
  1. 现在,我们已经检索并输出了板的根目录上所有路径的排序列表。我们将使用以下代码块仅列出位图图像文件:
>>> images = [i for i in paths if i.endswith('.bmp')]
>>> images
['joke_01_question.bmp', 'joke_01_response.bmp', 'joke_02_question.bmp', 'joke_02_response.bmp', 'joke_03_question.bmp', 'joke_03_response.bmp', 'joke_04_question.bmp', 'joke_04_response.bmp']
  1. 我们可以进一步扩展它,并且只列出图像文件,如以下代码块所示:
>>> questions = [i for i in paths if i.endswith('question.bmp')]
>>> questions
['joke_01_question.bmp', 'joke_02_question.bmp', 'joke_03_question.bmp', 'joke_04_question.bmp']
>>> 
  1. 以下代码块将选择第一个问题图像并将其保存到变量中:
>>> question = questions[0]
>>> question
'joke_01_question.bmp'
  1. 以下代码块可用于根据问题图像计算笑话响应图像的名称:
>>> response = question.replace('question.bmp', 'response.bmp')
>>> response
'joke_01_response.bmp'
  1. 我们将使用以下代码块确认计算出的响应映像作为文件存在:
>>> response in paths
True
  1. 以下代码应放入main.py文件中:
import os

def get_questions():
    paths = sorted(os.listdir())
    return [i for i in paths if i.endswith('question.bmp')]

def main():
    questions = get_questions()
    for question in questions:
        response = question.replace('question.bmp', 'response.bmp')
        print(question, response)

main()

执行此脚本时,它将列出所有问题图像并计算它们的相关响应图像。

它是如何工作的。。。

此配方中的get_questions函数将文件名的排序列表保存在paths变量中。然后,它通过检查文件名中是否出现question.bmp字符串来过滤列表,使其仅包含问题图像。然后,该函数将返回此筛选列表。

main 函数调用get_questions函数并将其结果保存到questions变量。当我们将文件名中的question.bmp值替换为response.bmp时,每个问题都会循环出现,并计算其响应图像。然后在循环的下一次迭代开始之前打印问题和响应文件名。

还有更多。。。

许多图像将用于创建笑话讲述机。我们本可以将必要图像的名称保存在脚本本身中,而不是直接在文件系统中列出它们。但是这个方法更好,因为它避免了我们在应用程序中直接硬编码图像列表。这意味着,我们可以有 5 个笑话,甚至 50 在董事会上,我们不必改变我们的应用程序的代码。

每次我们启动讲笑话的机器,它都会自动抓取最新的笑话图片列表。以下屏幕截图显示了笑话问题和回答,这些问题和回答将在下一个创建笑话讲述机的配方中使用:

您可以看到,文件名遵循一个简单的命名约定,以便在图像查看器中查看每个问题和响应时,您可以轻松地看到它们。这种命名约定还使计算特定问题图像的相关响应图像变得简单。

另见

以下是有关此配方的一些参考资料:

创造一个讲笑话的机器

此配方将向您展示如何列出特定目录中的所有图像文件。在我们正在创建的笑话讲述机中,每个笑话问题和回答都将作为一对图像提供。本食谱将向我们展示如何在电路板上列出所有位图图像。

然后,我们将扩展此功能以进一步过滤列表,以便手头有笑话问题的所有位图图像。如果您想创建一个项目,在该项目中检索图像或音频文件列表,以便在项目中显示或播放它们,则此配方将对您有所帮助。

准备

您需要访问 Adafruit HalloWing 设备上的 REPL 才能运行此配方中提供的代码。

怎么做。。。

按照以下步骤学习如何创建讲笑话机器:

  1. 在 REPL 中运行以下代码行:
>>> from displayio import OnDiskBitmap, ColorConverter, TileGrid, Group
>>> import board
>>> import random
>>> import time
>>> import touchio
>>> import os
  1. 我们现在已经导入了所有必要的模块。以下代码块将创建一个TouchIn对象:
>>> touch = touchio.TouchIn(board.TOUCH1)
>>>
  1. 在以下代码块中,我们将检查触摸板的状态:
>>> touch.value
False
  1. 在执行以下代码块时触摸键盘:
>>> touch.value
True
  1. 以下代码块将定义wait_for_touch功能,该功能将保持循环,直到检测到触摸事件:
>>> def wait_for_touch(touch):
...     while not touch.value:
...         print('waiting...')
...         time.sleep(0.1)
...         
...         
... 
>>> 
  1. 我们将使用下面的代码块调用wait_for_touch。执行此功能后,在触摸键盘之前等待片刻,以确认一旦检测到触摸事件,该功能从其while循环返回:
>>> wait_for_touch(touch)
waiting...
waiting...
waiting...
waiting...
>>> 
  1. 以下代码块将问题图像列表保存在questions变量中:
>>> def get_questions():
...     paths = sorted(os.listdir())
...     return [i for i in paths if i.endswith('question.bmp')]
...     
...     
... 
>>> 
>>> questions = get_questions()
>>> questions
['joke_01_question.bmp', 'joke_02_question.bmp', 'joke_03_question.bmp', 'joke_04_question.bmp']
  1. 我们将使用以下代码块从问题列表中随机选择一个问题:
>>> question = random.choice(questions)
>>> question
'joke_04_question.bmp'
  1. 以下代码应放入main.py文件中:
from displayio import OnDiskBitmap, ColorConverter, TileGrid, Group
import board
import random
import time
import touchio
import os

def show_image(path):
    print('showing image', path)
    with open(path, 'rb') as f:
        bitmap = OnDiskBitmap(f)
        pixel_shader = ColorConverter()
        sprite = TileGrid(bitmap, pixel_shader=pixel_shader)
        group = Group()
        group.append(sprite)
        board.DISPLAY.show(group)
        board.DISPLAY.wait_for_frame()

def wait_for_touch(touch):
    while not touch.value:
        print('waiting...')
        time.sleep(0.1)

def get_questions():
    paths = sorted(os.listdir())
    return [i for i in paths if i.endswith('question.bmp')]

def main():
    touch = touchio.TouchIn(board.TOUCH1)
    questions = get_questions()
    while True:
        question = random.choice(questions)
        response = question.replace('question.bmp', 'response.bmp')
        show_image(question)
        wait_for_touch(touch)
        show_image(response)
        wait_for_touch(touch)

main()

执行此脚本时,它将启动笑话讲述机,并让您在每次按下触摸板时在显示屏上看到笑话问题和回答。

它是如何工作的。。。

main函数创建一个TouchIn对象,该对象连接到板上的第一个触摸板连接器。通过调用get_questions()函数并将返回的列表保存在questions变量中,可以检索问题图像列表。

然后启动无限事件循环,该循环首先选择一个随机问题并计算该问题的相关响应图像。然后通过调用show_image功能在屏幕上显示问题图像。然后调用wait_for_touch函数,该函数每 100 毫秒循环检查一次触摸事件。

一旦检测到触摸事件,该函数将返回,然后调用show_image函数以显示响应图像。再次调用wait_for_touch函数,以便用户在决定通过触摸板加载另一个问题之前可以看到响应。按下触摸板后,当前循环迭代结束,过程以随机选择的新问题再次开始。

还有更多。。。

讲笑话的机器是一个有趣的方式来使用这个板的输入和输出潜力。它使用电路板的图形显示器显示不同的笑话问题和回答,以及电容式触摸传感器作为输入,使应用程序加载下一个问题或显示加载问题的答案。

这个基本配方可以通过多种方式进行扩展。由于该板配有四个触摸板,您可以创建一个简单的菜单系统,人们可以从中选择不同类别的笑话。您甚至可以创建一个数字骰子项目,方法是在每次按下触摸板时显示骰子的六个面,并显示一个随机面。

另见

以下是有关此配方的一些参考资料: