本章将向您介绍从 Adafruit Circuit 游乐场 Express 附带的多个传感器读取传感器数据的方法。我们将介绍温度和光线传感器,以及运动传感器,您还将了解如何使电路板对传感器事件做出反应,例如电路板受到震动或光线级别发生变化。能够访问这些丰富的传感器数据可以使各种项目成为可能。例如,您可以创建一个项目,如果检测到的温度超过某个级别,该项目会发出警报蜂鸣。通过学习如何读取和处理这些传感器数据,您可以实现各种嵌入式项目。
在本章中,我们将介绍以下主题:
- 快速传感器电路
- 读取温度读数
- 从光传感器读取亮度级别
- 创建测光表
- 从运动传感器读取数据
- 检测单抽头或双抽头
- 检测到震动
- 震动时发出嘟嘟声
本章将使用三种不同的硬件传感器从环境中获取传感器读数。以下是热敏电阻的照片,显示了温度传感器的位置:
Courtesy of adafruit.com
下图显示了设备上可用的光传感器:
Courtesy of adafruit.com
下图显示了可用于检测运动的加速计,以及电路板上的轻敲和双击撞击:
Courtesy of adafruit.com
现在让我们看看我们的第一份食谱。
在本食谱中,我们将学习如何创建一个循环,从温度传感器重复读取当前温度并打印出来。这将让我们对传感器进行实验,看看它对温度变化的反应。只要您需要在项目中加入温度读数,就可以使用此配方中的方法。
要运行此配方中提供的代码,您需要访问电路操场 Express 上的 REPL。
按照以下步骤学习如何读取温度读数:
- 在 REPL 中运行以下代码行。输出显示室温约为 25°C:
>>> from adafruit_circuitplayground.express import cpx
>>> import time
>>> cpx.temperature
25.7499
- 现在,在进行下一次读数时,用手指按压温度传感器,利用体温增加温度传感器读数:
>>> cpx.temperature
30.031
- 温度应该上升了好几度。如果运行以下代码,则应返回浮点数:
>>> start = time.monotonic()
>>> start
27.409
- 等待几秒钟,然后执行以下代码行。它将计算自您将值分配给 start 变量以来的秒数:
>>> time.monotonic() - start
11.37
- 如果运行以下代码,则所有局部变量及其值的列表应显示为字典:
>>> locals()
{'time': <module 'time'>, 'start': 60.659, '__name__': '__main__'}
>>>
- 以下代码应放入
main.py
文件中,执行时将重复打印当前经过的时间和当前温度读数:
from adafruit_circuitplayground.express import cpx
import time
start = time.monotonic()
while True:
elapsed = time.monotonic() - start
temp = cpx.temperature
print('{elapsed:.2f}\t{temp}'.format(**locals()))
time.sleep(0.1)
代码的前几行导入 Circuit Playplace Express 库和time
模块。cpx
对象公开了一个名为temperature
的属性—无论何时访问该值,该属性都会将热敏电阻的当前温度读数作为浮点数返回。
该值以摄氏温度刻度表示。记录开始时间,以便计算每个温度读数的经过时间。然后,脚本进入无限循环,计算经过的时间并获得每个循环迭代的温度读数。
经过的时间和温度用制表符分隔符打印。在循环的下一次迭代开始之前应用 0.1 秒的延迟。
本装置上的温度传感器为负温度系数(NTC热敏电阻。该元件是一个电阻,其电阻随温度变化而变化。通过测量它的电阻,我们可以得到温度的读数。对于 NTC 热敏电阻,电阻将随着温度的升高而降低。
在此配方中,时间和温度数据以制表符分隔的格式输出。这种格式使得将数据移动到其他应用程序进行分析变得很容易。下图是使用此配方中主脚本输出的数据生成的:
脚本运行 60 秒后,从 REPL 获取输出并复制粘贴到电子表格程序 LibreOffice Calc 中。默认情况下,制表符分隔符将时间和温度数据分隔为各自的列。然后,使用该数据表生成了x-y散点图。
像这样绘制传感器数据,可以很容易地可视化温度读数随时间的变化。在此特定数据集中(在脚本执行开始时),温度传感器读取的环境室温约为 26°C。在脚本执行大约 10 秒钟后,触摸传感器将其加热至近 30°C。
这可以从上图中温度的急剧升高中看出,温度升高发生在 10 秒标记处。松开传感器后,它开始缓慢的冷却过程,直到传感器在 40 秒的时间内冷却到超过 27°C 标记。
以下是有关此配方的一些参考资料:
- 有关温度特性的文件可在中找到 https://circuitpython.readthedocs.io/projects/circuitplayground/en/latest/api.html#adafruit_circuitplayground.express.Express.temperature 。
- 有关 CircuitPython
time
模块的文档可在中找到 https://circuitpython.readthedocs.io/en/3.x/shared-bindings/time/init.html 。 - 内置
locals
功能的文档可在中找到 https://docs.python.org/3/library/functions.html#locals 。 - 有关热敏电阻工作原理的详细信息,请参见https://www.omega.com/prodinfo/thermistor.html 。
- LibreOffice Calc 应用程序的项目页面和应用程序下载可在找到 https://www.libreoffice.org/ 。
在本配方中,我们将学习如何创建一个循环,该循环将重复读取来自光传感器的当前光亮度。从传感器获取实时读数是一种有趣的方法,可以用它来测试传感器对不同光源的灵敏度。
最终,此配方中的技术可以帮助您构建与环境交互的项目,具体取决于是否存在灯光。
要运行此配方中提供的代码,您需要访问电路操场 Express 上的 REPL。
按照以下步骤学习如何从光传感器读取亮度级别:
- 在 REPL 中执行以下代码块:
>>> from adafruit_circuitplayground.express import cpx
>>> cpx.light
5
- 输出的数字是房间的亮度。在正常照明条件下,这应该是一个较低的数字。
- 现在,在运行以下代码块时,用手电筒照射光传感器:
>>> cpx.light
308
- 您应该看到该值上升到更高的值。应将以下代码放入
main.py
文件中,并在执行时重复打印从光传感器读取的当前亮度:
from adafruit_circuitplayground.express import cpx
import time
while True:
print(cpx.light)
time.sleep(0.1)
代码的前几行导入 Circuit Playplace Express 库和time
模块。cpx
对象公开了一个名为light
的属性。此属性将返回来自灯光传感器的当前灯光级别读数。该值使用勒克斯单位表示,勒克斯单位是测量照度的单位。
在这个脚本中,运行一个无限循环,它打印当前的灯光级别,然后在下一次迭代开始之前休眠 0.1 秒。
使用光传感器的一种方便方法是使用大多数智能手机上的手电筒。这个手电筒足够亮,可以在 Circuit Playerd Express 上的灯光读数中产生巨大的差异。运行此配方中的主脚本时,观察当手电筒离传感器越来越近时,值是如何变化的。
这个装置上的光传感器是一个光电晶体管。这种类型的器件是一种晶体管,当暴露在不同的光照水平下时,将导致流向其电路的电流产生差异。可以读取这些电气变化,然后计算光照水平。
以下是一些关于该配方的参考资料:
- 有关
light
财产的文件可在找到 https://circuitpython.readthedocs.io/projects/circuitplayground/en/latest/api.html#adafruit_circuitplayground.express.Express.light 。 - 有关光电晶体管工作原理的更多详细信息,请参见https://www.elprocus.com/phototransistor-basics-circuit-diagram-advantages-applications/ 。
在这个配方中,我们将使用 10 个 Neopixel 来创建一个显示当前光照级别的环。随着光线的增加和减少,光环会变得越来越小。这个食谱将向你展示一种让你的项目与光互动的方法。它还将展示一种通用技术,用于将像素环转换为 10 个级别的量具,您可以在各种项目中使用。
要运行此配方中提供的代码,您需要访问电路操场 Express 上的 REPL。
按照以下步骤学习如何创建测光表:
- 使用 REPL 运行以下代码行:
>>> from adafruit_circuitplayground.express import cpx
>>> import time
>>>
>>> BLACK = 0x000000
>>> BLUE = 0x0000FF
>>> MAX_LUX = 330
>>> cpx.pixels.brightness = 0.10
>>>
>>> def gauge(level):
... cpx.pixels[0:level] = [BLUE] * level
...
...
...
>>> gauge(2)
- 此时,您应该看到前两个像素变为蓝色。运行以下代码行以查看前五个像素变为蓝色:
>>> gauge(5)
- 以下代码应放入
main.py
文件中,当执行时,它将创建一个随着亮度变亮变暗而变大变小的测光仪:
from adafruit_circuitplayground.express import cpx
import time
BLACK = 0x000000
BLUE = 0x0000FF
MAX_LUX = 330
cpx.pixels.brightness = 0.10
def gauge(level):
cpx.pixels[0:level] = [BLUE] * level
last = 0
while True:
level = int((cpx.light / MAX_LUX) * 10)
if level != last:
cpx.pixels.fill(BLACK)
gauge(level)
last = level
time.sleep(0.05)
代码的前几行导入 Circuit Playplace Express 库和time
模块。颜色代码是为蓝色和黑色定义的。然后将亮度设置为舒适的水平。然后定义gauge
函数。此函数接收单个整型参数,其值的范围应为 0 到 10。该值将用于确定在像素环中有多少像素将变为蓝色。此功能创建类似于经典仪表的视觉显示,根据值的级别显示较小或较大的环。
然后,last
变量被初始化。此变量用于跟踪自上次循环以来仪表液位是否发生了变化。这个额外的步骤是为了防止由于不必要地在每个循环中关闭和打开像素而导致像素闪烁。通过获取当前光照级别并将其除以最大可能值(该板上恰好为 330)来计算仪表级别。
然后将该值乘以 10,即仪表中的液位数。如果仪表级别已更改,则将关闭所有像素,然后显示正确的仪表级别。这个过程是在无限循环的每次迭代中完成的,每个循环之间有 50 毫秒的延迟,以便在与光传感器交互时产生响应的感觉。
在此配方中,显示仪表的功能有意保留在其自身的功能中,以鼓励重用。它可以在其他项目中使用,也可以保存在自己的模块中,只要您需要使用主板附带的像素将信息显示为仪表,就可以导入并使用该模块。
这个方法的另一个方面是必须做额外的工作来解决不必要地反复打开和关闭像素时出现的灯光闪烁问题。当您同时更改多个像素的状态时,如果您不仔细执行实现,可能会出现闪烁问题。就测光表的功能而言,这不是一个主要问题;它更多的是创造一个更愉快的视觉体验时,人们使用测光表。
以下是一些关于该配方的参考资料:
- 使用 Circuit Playdry Express pixels 创建声级计的项目可在找到 https://learn.adafruit.com/adafruit-circuit-playground-express/playground-sound-meter 。
- 有关什么是电表及其用途的更多详细信息,请访问https://shuttermuse.com/glossary/light-meter/ 。
在此配方中,我们将创建一个循环,不断读取加速计的数据,并打印x、y和z轴的数据。打印输出将帮助我们试验传感器如何对振动电路板或向不同方向倾斜电路板做出反应。一旦你了解了传感器的工作原理,你就可以开始将它整合到项目中,让你的电路板对倾斜或加速度做出反应。
要运行此配方中提供的代码,您需要访问电路操场 Express 上的 REPL。
按照以下步骤学习如何从运动传感器读取数据:
- 在 REPL 中运行以下代码行,同时将电路板放置在水平面上,其按钮朝上:
>>> from adafruit_circuitplayground.express import cpx
>>> cpx.acceleration.z
9.46126
- 当电路板的按钮朝下放置时,运行以下代码块:
>>> cpx.acceleration.z
-9.30804
- 应将以下代码放入
main.py
文件中,执行时将持续打印来自加速计的当前x、y和z轴数据:
from adafruit_circuitplayground.express import cpx
import time
while True:
x, y, z = cpx.acceleration
print('x: {x:.2f} y: {y:.2f} z: {z:.2f}'.format(**locals()))
time.sleep(0.1)
代码的前几行导入 Circuit Playplace Express 库和time
模块。启动一个无限循环,该循环将在每个循环期间从加速计获取读数。读数被解包到x、y和z变量中。然后,在脚本休眠 0.1 秒并开始下一次迭代之前,打印每个轴的值。
当脚本运行时,尝试向不同方向倾斜板。这个传感器相当灵敏,可以给你一个相当准确的读数,这与电路板的倾斜有关。除了检测电路板的方向外,它还可用于检测三个轴中任何一个轴上的加速度。当脚本运行时,也向不同方向摇动电路板,您应该会看到与加速度上升相关的读数。根据摇动板的方向,不同的轴应做出相应的反应。
以下是一些关于该配方的参考资料:
- 有关
acceleration
财产的文件可在找到 https://circuitpython.readthedocs.io/projects/circuitplayground/en/latest/api.html#adafruit_circuitplayground.express.Express.acceleration 。 - 更多有关 Circuit Playway Express 附带的加速计的详细信息,请访问https://learn.adafruit.com/circuit-playground-lesson-number-0/accelerometer 。
在本食谱中,我们将学习如何配置电路板以检测单次或双次抽头。来自加速计的传感器数据将用于检测这些抽头事件。这个食谱向您展示了如何创建能够对人们点击电路板做出反应的应用程序。
要运行此配方中提供的代码,您需要访问电路操场 Express 上的 REPL。
按照以下步骤学习如何检测单次或双次点击:
- 在 REPL 中执行以下代码块:
>>> from adafruit_circuitplayground.express import cpx
>>> cpx.detect_taps = 1
>>> cpx.tapped
False
- 轻触电路板一次,然后运行以下代码块。您应该为第一个值获取一个
True
值,表示检测到一个抽头,然后在下一次检查时获取一个False
值,表示自上次检查以来没有检测到新的抽头:
>>> cpx.tapped
True
>>> cpx.tapped
False
- 以下代码应放入
main.py
文件中,执行时,将持续打印自上次检查以来是否检测到抽头:
from adafruit_circuitplayground.express import cpx
import time
cpx.detect_taps = 1
while True:
print('tap detected:', cpx.tapped)
time.sleep(0.1)
代码的前几行导入 Circuit Playplace Express 库和time
模块。抽头检测算法配置为通过将detect_taps
设置为1
来检测单个抽头。
一个无限循环被启动,它将检索每个循环上的tapped
属性的值。仅当自上次检查抽头后加速计检测到单个抽头时,此属性才会返回True
。然后调用sleep
函数,以在开始下一次迭代之前产生 0.1 秒的延迟。
通过将detect_taps
设置为2
来修改脚本。当您再次运行它时,请尝试在电路板上执行一些单独的点击。它不应该记录任何东西。
现在尝试执行一些双击。您应该可以看到它们被检测到。试着改变你用来轻敲电路板的力度,看看在检测到轻敲之前需要多大的力度。
以下是有关此配方的一些参考资料:
- 有关
detect_taps
财产的文件可在找到 https://circuitpython.readthedocs.io/projects/circuitplayground/en/latest/api.html#adafruit_circuitplayground.express.Express.detect_taps 。 - 有关
tapped
财产的文件可在找到 https://circuitpython.readthedocs.io/projects/circuitplayground/en/latest/api.html#adafruit_circuitplayground.express.Express.tapped 。 - 有关电路板抽头检测能力的更多详细信息,请参见https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/tap 。
在本食谱中,我们将学习如何轮询shake
方法,并在电路板晃动时打印出来。创建能够响应设备震动的项目真的很有趣。该电路板还可以进行配置,以便您可以在将其注册为抖动之前指定是需要轻微抖动还是剧烈抖动。这可以开辟新的创造性方式,让人们与您的设备进行交互。
要运行此配方中提供的代码,您需要访问电路操场 Express 上的 REPL。
按照以下步骤学习如何检测震动:
- 使用 REPL 运行以下代码行:
>>> from adafruit_circuitplayground.express import cpx
>>> cpx.shake(20)
False
- 运行以下代码块时,反复摇晃电路板:
>>> cpx.shake(20)
True
- 应将以下代码放入
main.py
文件中,执行时,将持续打印电路板当前是否正在晃动:
from adafruit_circuitplayground.express import cpx
import time
while True:
print('shake detected:', cpx.shake())
time.sleep(0.1)
代码的前几行导入 Circuit Playplace Express 库和time
模块。启动一个无限循环,它将在每个循环上打印shake
方法的结果。此方法将返回True
或False
,具体取决于当前是否正在晃动电路板。然后调用sleep
函数以在开始下一次迭代之前产生 0.1 秒的延迟。
修改脚本,并将值20
作为第一个参数赋予shake
函数。现在,运行脚本并尝试摇晃它。您应该发现,板注册震动事件所需的力较小。第一个参数shake_threshold
的默认值为30
,该值越低,电路板对检测震动越敏感。不要将该值设置为10
或更低,否则它将过于敏感,并会持续认为它已检测到震动。
以下是一些关于该配方的参考资料:
- 有关
shake
方法的文件可在中找到 https://circuitpython.readthedocs.io/projects/circuitplayground/en/latest/api.html#adafruit_circuitplayground.express.Express.shake 。 - 使用
shake
方法的示例见https://learn.adafruit.com/circuitpython-made-easy-on-circuit-playground-express/shake 。
在本食谱中,我们将学习如何使电路板在每次摇动时发出嘟嘟声。这是一种让董事会对运动做出反应的有趣方式。同样的方法也可以用来使像素对震动做出响应,而不仅仅是嘟嘟声。
要运行此配方中提供的代码,您需要访问电路操场 Express 上的 REPL。
按照以下步骤学习如何使电路板在每次摇动时发出嘟嘟声:
- 在 REPL 中运行以下代码行;您应该会听到一声蜂鸣声:
>>> from adafruit_circuitplayground.express import cpx
>>> cpx.play_tone(900, 0.2)
- 应将以下代码放入
main.py
文件中,执行时,每次摇动板时都会发出嘟嘟声:
from adafruit_circuitplayground.express import cpx
import time
while True:
if cpx.shake(20):
cpx.play_tone(900, 0.2)
time.sleep(0.1)
代码的前几行导入 Circuit Playplace Express 库和time
模块。一个无限循环被启动,它将检查电路板当前是否正在晃动。如果检测到震动事件,则会发出短嘟嘟声 0.2 秒。在此之后,检查电路板是否休眠 0.1 秒,然后再开始该过程。
您可以将滑动开关合并到此配方中,以便人们可以根据滑动开关的位置选择高或低震动阈值。通过这种方式,滑动开关可用于使振动易于或难以检测。你可以创建一个游戏,每次摇动都会增加一个计数器并发出一声蜂鸣音。
当计数器达到 10 时,您可以播放胜利旋律。然后,谁先达到 10 次摇晃,谁就赢了。使用摇动而不是按下按钮与设备交互是改变人们与项目交互方式的一种有趣方式。
以下是一些关于该配方的参考资料:
- 有关加速计工作原理的指南,请参见https://www.dimensionengineering.com/info/accelerometers 。
- 有关用于与车载加速计交互的 Python 库的文档可在中找到 https://circuitpython.readthedocs.io/projects/lis3dh/en/latest/api.html 。