- 2024-08-31
-
发表了主题帖:
【Follow me第二季第一期】任务汇总帖
本帖最后由 cyz6668 于 2024-9-29 13:04 编辑
大家好,我是cyz6668,今天向大家分享一下我参与Follow me第一期的任务汇总。汇总视频见【【Follow me第二季第一期】任务汇总(by cyz6668)-【Follow me第二季第一期】任务汇总(by cyz6668)-EEWORLD大学堂】。
项目简介:搭配必购板子Adafruit Circuit Playground Express完成下方任务。
入门任务(必做):开发环境搭建,板载LED点亮
基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
创意任务:有创意的可穿戴装饰——可结合多种传感器和灯光效果展示
物料图片:主要用了开发板Adafruit Circuit Playground Express。
设计思路分开任务详细介绍。
本期任务使用的是Adafruit这块开发板,我选择使用Circuit Python对它进行开发。
1. 入门任务:开发环境的搭建和板载LED的点亮
见【【Follow me第二季第1期】 入门任务:板载LED点亮以及跑马灯效果 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)】。
首先我们需要下载好烧录所需的.uf2文件和CircuitPython固件库。下载好以后我们将开发板通过USB连接到电脑,电脑识别出新的驱动器CPLAYBOOT,这标志着连接成功。
将之前下载好的.uf2文件复制到驱动器中,等待一段时间,板子呈现红灯全亮的状态,并且之前的驱动器弹出并且重新被识别为CIRCUITPY,即可烧录Python程序。
之后我们下载本地的Mu Editor用于编写开发板的代码,选择使用Circuit Python,开发环境就搭建完成了。之后将下载好的固件库复制到板子中,这些都是Circuit Playground Library中的函数,提供了各种功能和参考例程。后续的任务都会基于此进行。
我们试着点亮一下板载LED,代码如下:
from adafruit_circuitplayground import cp
while True:
cp.red_led =True
实现板载LED灯的点亮效果如下,可以看到D13位置的LED灯点亮。
2. 基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
·见【【Follow me第二季第1期】 入门任务:板载LED点亮以及跑马灯效果 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)】。
这部分任务需要使用到板子外围的一圈LED灯,并且依次去点亮并赋予不同的颜色。我们使用如下代码亮灯,其中i表示需要点亮的LED灯的编号,三元数组(R,G,B)用于设置灯的颜色。
为了方便实现跑马灯的颜色变换,我们预先设置了一个颜色的列表color,用于存储可能用到的颜色,然后只需要每一盏灯按顺序依次取一种颜色即可,超过取色的列表范围就从头开始取。同时在每一次循环中,LED灯的起始颜色会更新为颜色列表中的下一个颜色,这样,整个LED灯带就会呈现出流动的光效。
具体的代码如下:
from adafruit_circuitplayground import cp
cp.pixels.brightness = 0.1
num_pixels = 10
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255),
(0, 255, 255), (255, 127, 0), (127, 255, 0), (127, 0, 255), (0, 127, 255)]
while True:
for i in range(num_pixels):
start_color = i
for j in range(num_pixels):
cp.pixels[j] = colors[(i+j)%10]
3. 基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
见【【Follow me第二季第1期】 普通任务:光照传感器和温度传感器 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)】。
这个任务主要涉及温度和光照传感器的使用。
首先是光照传感器,通过cp.light就可以读取光照传感器采集的数值。此外,教程进一步提供了一个量化光照强度并转换为LED亮灯数量的函数示例。此函数将传感器读数转换为0到9之间的整数,代表亮灯的数量。
其次再看温度传感器,使用的方法和光照传感器是一样的,通过cp.temperature,可以获取以摄氏度为单位的温度读数。同样地,为了量化温度读数,教程推荐了另一种方法。这种方法不仅直观,而且具有更高的通用性和可复用性,便于迁移至其他传感器的应用。
回到实际的任务,我们先通过以下的代码,打印一下当前的光照强度和温度,作为我们设置的舒适温度的标准。可以看到光照强度大约是160左右,温度是26℃左右。基于此,我们设定了光照的上限为200,下限为100;温度的上限为30℃,下限为24℃。
我们对量化函数进行了合并,分别用左右两侧各5盏LED来分别量化表示光照和温度。同时考虑到实际的采集值可能会超过我们设置的阈值,防止两边亮灯互相干扰,此函数限制了亮灯数量的最大值为5,确保了LED显示的一致性和直观性。
LED灯的状态更新通过编写专门的函数实现,该函数不仅考虑了LED灯的编号顺序,还通过颜色编码区分了不同的环境状态。光照部分都亮白灯;温度部分,适宜温度时亮绿灯,低于适宜温度时亮蓝灯,高于适宜温度时亮红灯,以示区别。
最后在主循环中去调用这个更新LED状态的函数,将所有的灯按照更新好的状态点亮。我们可以看到左边的温度指示灯和右边的光照指示灯被点亮,视频中也演示了当用手指遮挡光线或者触碰温度传感器,改变光照强度和温度的时候,出现的指示灯数量变化。
具体的代码如下:
import time
from adafruit_circuitplayground import cp
cp.pixels.auto_write = False
cp.pixels.brightness = 0.1
minimum_light = 0
maximum_light = 200
minimum_temp = 25
maximum_temp = 32
pixels = [0] * 10
def scale_range(value, minimum_value, maximum_value):
return min(int((value - minimum_value) / (maximum_value - minimum_value) * 5), 5)
def update_leds(peak_light, peak_temp):
for i in range(10):
pixels[i] = (0, 0, 0)
for i in range(peak_light):
pixels[i] = (255, 255, 255)
if peak_temp < 3:
temp_color = (0, 0, 255)
elif peak_temp == 3:
temp_color = (0, 255, 0)
else:
temp_color = (255, 0, 0)
for i in range(10 - peak_temp, 10):
pixels[i] = temp_color
return pixels
while True:
print((cp.light,cp.temperature))
peak_light = scale_range(cp.light, minimum_light, maximum_light)
peak_temp = scale_range(cp.temperature, minimum_temp, maximum_temp)
pixels = update_leds(peak_light, peak_temp)
for i in range(10):
cp.pixels[i] = pixels[i]
cp.pixels.show()
time.sleep(0.05)
4. 基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
见【【Follow me第二季第1期】 普通任务:光照传感器和温度传感器 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)】。
我们的设计思路是通过固定光源照射开发板,并点亮板上所有LED灯来模拟环境光照。当物体接近时,会遮挡外部光源,导致光照传感器只能接收到来自板载LED的光,从而读数下降。相反,当物体非常接近时,其表面的反射作用会增强传感器的读数。基于这一原理,我们设定了当传感器读数异常升高时,触发蜂鸣器发出警报。
我们编写了以下代码来记录和绘制光照强度的变化曲线。在无遮挡和正常遮挡的情况下,光照传感器的采样值相对比较稳定,分别是120左右和5左右。但是当物体非常接近时,尽管光照传感器采样值出现增大,最大值可以超过250。我们将250设置为安全距离,但是因为物体移动或者不平整等原因,导致比较大的波动,可能会出现一些误判断的情况。
完整的代码如下:
import time
from adafruit_circuitplayground import cp
while True:
if cp.light < 140:
for i in range(10):
cp.pixels[i] = (0, 0, 255)
cp.pixels.show()
elif cp.light > 250:
for i in range(10):
cp.pixels[i] = (255, 0, 0)
cp.pixels.show()
cp.play_file("dip.wav")
else:
for i in range(10):
cp.pixels[i] = (0, 255, 0)
cp.pixels.show()
time.sleep(0.01)
在无遮挡时,LED显示绿色;当物体遮挡但距离较远时,LED显示蓝色;而当物体非常接近时,LED显示红色,并触发蜂鸣器报警。最终的结果如视频所示。
我们采用硬纸板是可以反光的,从而使得非常接近板子的时候反而能加强光照传感器的读数。此外,由于物体遮挡和接近板子之间必然经过正常光照的中间状态,可能会导致在某些适中距离下出现误判。未来,我们计划进一步研究如何有效利用红外模块,以提高接近检测的准确性和可靠性。
5. 进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
见【【Follow me第二季第1期】 进阶任务:不倒翁和创意可穿戴装饰 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)】。
我们将使用六轴加速度传感器,以实现一个动态的灯光效果,随着不倒翁的摇摆而变化。
该任务主要需要使用的传感器可以参考教程中的Acceleration部分。通过传感器可以获取x,y,z三轴的读数,这些读数会随着开发板的空间位置和倾斜情况而变化。利用这些参数,我们可以对LED灯的(R,G,B)三元组进行动态调整,以实现不倒翁在晃动过程中呈现出独特的灯光效果。
具体的实现代码已经在教程中提供,我们可以直接采用并进行适当的修改。
from adafruit_circuitplayground import cp
while True:
R = 0
G = 0
B = 0
x, y, z = cp.acceleration
print((x, y, z))
cp.pixels.fill(((R + abs(int(x))),
(G + abs(int(y))),
(B + abs(int(z)))))
根据不同的倾斜情况的传感器示数,可以调整RGB三色的配比,我们可以根据不同的倾斜情况实现不同的颜色变化。例如,当开发板平放时,灯光可以呈现蓝色;当板子垂直放置时,灯光可以呈现绿色;而当板子垂直后旋转,灯光则可以转变为红色。在视频演示中,我们可以观察到随着开发板的晃动,灯光效果随之不断变化。
6. 创意任务一:有创意的可穿戴装饰——可结合多种传感器和灯光效果展示
见【【Follow me第二季第1期】 进阶任务:不倒翁和创意可穿戴装饰 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)】。
我们设计了一款独特的可穿戴装饰,它不仅拥有绚丽的灯光效果,还具备音乐播放功能,让你在黑夜中也能享受快乐时光。这款装饰巧妙地结合了开发板的LED灯、蜂鸣器以及开关,为用户提供了丰富的互动体验。
在这款装饰中,我们使用了板载的LED灯和蜂鸣器,以及一个拨动开关和两个按键开关B。拨动开关用于在两种模式之间切换,而按键开关B则用于改变蜂鸣器的音调,使其能够演奏旋律。
当拨动开关置右时,LED灯进入自动变色模式。当拨动开关置左时,LED灯进入手动变色模式。此时,用户可以通过按下按键B来改变LED灯的颜色,同时蜂鸣器会播放预设的音调。通过连续长按按键B,可以实现蜂鸣器播放旋律,并且LED灯随着旋律顺滑地变换颜色。
以下是具体的代码实现,首先介绍如何实现LED灯的顺滑切换。
我们预设了一个RGB颜色的允许取值范围,以确保选取的颜色都是相对正色。然后,我们编写了一个颜色更新函数,每次只从R,G,B三个通道中随机选择一个进行参数在允许的取值内随机改变,这样就保证了连续两个颜色之间不会产生特别大的差异。同时,在每一次颜色改变后,我们都会检查RGB三者是否同时取到了0,如果是,则会将这一次改变的通道在除了0以外的值内重新随机选择。
其次我们介绍如何实现蜂鸣器的旋律播放。我们根据乐谱C调中低音do到高音do的频率,将一首乐曲Funky Town(鸡块旋转小曲)的旋律转换成频率的列表。每次检测到按键B被按下,蜂鸣器自动播放下一个音调。当按键B被长按时,就实现了旋律的连续播放。
最终把两者结合起来,具体代码如下:
import time
import random
from adafruit_circuitplayground import cp
color_values = [0, 63, 127, 191, 255]
current_color = [255, 255, 255]
cp.pixels.brightness = 0.1
tone_list = [454,454,422,454,-1,358,-1,358,454,550,518,454,
358,358,326,358,-1,262,-1,262,358,454,422,358]
def change_color(current_color):
channels = ['R', 'G', 'B']
channel = random.choice(channels)
new_value = random.choice(color_values)
if channel == 'R':
current_color[0] = new_value
elif channel == 'G':
current_color[1] = new_value
else:
current_color[2] = new_value
if current_color == [0, 0, 0]:
new_value = random.choice(color_values[1:])
if channel == 'R':
current_color[0] = new_value
elif channel == 'G':
current_color[1] = new_value
else:
current_color[2] = new_value
return current_color
flag = 0
while True:
for i in range(10):
cp.pixels[i] = current_color
if cp.switch:
current_color = current_color
if cp.button_b:
cp.play_tone(tone_list[flag], 0.1)
current_color = change_color(current_color)
flag = (flag + 1)%24
else:
flag = 0
current_color = change_color(current_color)
cp.pixels.show()
time.sleep(0.1)
在视频演示中,我们可以看到,当拨动开关置右时,LED灯自动切换颜色;当拨动开关置左且按键B被按下时,LED灯手动切换颜色,同时蜂鸣器播放旋律。这一互动体验不仅增加了装饰的趣味性,也提升了用户的参与感。
对本次活动的心得体会与建议:
参加这次电子开发板试玩活动,我收获颇丰。
我的技术水平通过这次学习得到提升,我通过实际操作,我对这款开发板的特性和使用方法有了全面的了解,提升了我的硬件编程和调试技能。
对我的创新思维也有启发作用。看到其他同学的创意项目,激发了我的创新思维,启发我在未来的项目中尝试更多新的想法。
团队合作:通过与小组成员的合作,我学会了如何在团队中有效沟通和协作,这对于任何项目都是非常重要的。
社区交流:活动中认识了很多志同道合的朋友,建立了宝贵的联系。这些交流不仅有助于技术上的成长,也为未来可能的合作打下了基础。
总之,这次活动不仅让我学到了新的知识和技术,更重要的是激发了我对电子开发的热情。我相信这些经验和心得将对我的未来发展大有裨益。
我希望后面可以推出更多相关的活动,更高难度的工作,并且可以有相关更详尽的课程学习。
以上就是这次任务的汇报,代码暂时还没有通过审核,附在帖子后面了,欢迎大家批评指正!
-
加入了学习《【Follow me第二季第一期】任务汇总(by cyz6668)》,观看 【Follow me第二季第一期】任务汇总(by cyz6668)
-
上传了资料:
【Follow me第二季第一期】任务汇总Code(by cyz6668)
-
发表了主题帖:
【Follow me第二季第1期】 进阶任务:不倒翁和创意可穿戴装饰
继续来挑战一下进阶任务和创意任务。
1. 进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
在本次进阶任务中,我们将探索Adafruit开发板的六轴加速度传感器,以实现一个动态的灯光效果,随着不倒翁的摇摆而变化。这一任务的核心在于理解并应用加速度传感器的读数,以控制LED灯的颜色变化。
该任务主要需要使用的传感器可以参考教程中的Acceleration部分【Acceleration | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】,通过cp.acceleration就可以获取传感器的x,y,z三轴的读数。虽然这些读数可能初看起来有些抽象,但它们实际上代表了开发板在空间中的位置和倾斜角度。这些读数会随着开发板的空间位置和倾斜情况而变化,为我们提供了丰富的数据来驱动灯光效果的变化。
利用这些参数,我们可以对LED灯的(R,G,B)三元组进行动态调整,以实现不倒翁在晃动过程中呈现出独特的灯光效果。具体的实现代码已经在教程中提供,我们可以直接采用并进行适当的修改,如下所示:
from adafruit_circuitplayground import cp
while True:
R = 0
G = 0
B = 0
x, y, z = cp.acceleration
print((x, y, z))
cp.pixels.fill(((R + abs(int(x))), (G + abs(int(y))), (B + abs(int(z)))))
根据不同的倾斜情况的传感器示数,可以调整RGB三色的配比,我们可以根据不同的倾斜情况实现不同的颜色变化。例如,当开发板平放时,灯光可以呈现蓝色;当板子垂直放置时,灯光可以呈现绿色;而当板子垂直后旋转,灯光则可以转变为红色。在视频演示中,我们可以观察到随着开发板的晃动,灯光效果随之不断变化,为不倒翁增添了一份动态的美感。
视频演示见视频的前半部分。
2. 创意任务一:有创意的可穿戴装饰——可结合多种传感器和灯光效果展示
我们设计了一款独特的可穿戴装饰,它不仅拥有绚丽的灯光效果,还具备音乐播放功能,让你在黑夜中也能享受快乐时光。这款装饰巧妙地结合了开发板的LED灯、蜂鸣器以及开关,为用户提供了丰富的互动体验。
在这款装饰中,我们使用了板载的LED灯和蜂鸣器,以及一个拨动开关和两个按键开关B。拨动开关用于在两种模式之间切换,而按键开关B则用于改变蜂鸣器的音调,使其能够演奏旋律。LED和蜂鸣器的使用在之前的普通任务中都已经介绍过,这里就不再赘述。
简单介绍一下开发板上的两种开关,在教程中分别是Slide Switch【Slide Switch | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】和Buttons【Buttons | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】。
开关的调用非常简单,用cp.switch和cp.button_a(/b)就可以分别访问拨动开关和两个按键开关的状态了。当拨动开关置右时,输出为True;当按键开关按下时,输出同样为True。
接下来分别介绍我们设计的创意装饰的两种不同模式:
当拨动开关置右时,LED灯进入自动变色模式。我们设计了一个颜色变换函数,确保在变色过程中颜色之间的过渡更加平滑,避免了突兀的颜色变化。同时,该模式确保LED灯始终处于点亮状态,不会出现黑色灭灯的情况。
当拨动开关置左时,LED灯进入手动变色模式。此时,用户可以通过按下按键B来改变LED灯的颜色,同时蜂鸣器会播放预设的音调。通过连续长按按键B,可以实现蜂鸣器播放旋律,并且LED灯随着旋律顺滑地变换颜色。
以下是具体的代码实现,首先介绍如何实现LED灯的顺滑切换。
我们预设了一个RGB颜色的允许取值范围,指定为[0, 63, 127, 191, 255],以确保选取的颜色都是相对正色。然后,我们编写了一个颜色更新函数,每次只从R,G,B三个通道中随机选择一个进行参数在允许的取值内随机改变,这样就保证了连续两个颜色之间不会产生特别大的差异。同时,在每一次颜色改变后,我们都会检查RGB三者是否同时取到了0,如果是,则会将这一次改变的通道在除了0以外的值内重新随机选择。具体的代码如下:
color_values = [0, 63, 127, 191, 255]
current_color = [255, 255, 255]
cp.pixels.brightness = 0.1
def change_color(current_color):
channels = ['R', 'G', 'B']
channel = random.choice(channels)
new_value = random.choice(color_values)
if channel == 'R':
current_color[0] = new_value
elif channel == 'G':
current_color[1] = new_value
else:
current_color[2] = new_value
if current_color == [0, 0, 0]:
new_value = random.choice(color_values[1:])
if channel == 'R':
current_color[0] = new_value
elif channel == 'G':
current_color[1] = new_value
else:
current_color[2] = new_value
return current_color
while True:
for i in range(10):
cp.pixels[i] = current_color
current_color = change_color(current_color)
cp.pixels.show()
time.sleep(0.1)
其次我们介绍如何实现蜂鸣器的旋律播放,根据教程中的Play Tone模块,我们可以通过cp.play_tone(262, 0.1)来播放音调,前者表示声音的频率(音高),后者表示持续的时间(应该存在最短的蜂鸣器持续时间,肯定不只0.1秒)。我们根据乐谱C调中低音do到高音do的频率,分别为[262,294,326,358,390,422,454,486],将一首乐曲Funky Town(鸡块旋转小曲)的旋律转换成频率的列表(列表中-1表示空拍,但是不知道什么原因依旧还有一声杂音)。每次检测到按键B被按下,蜂鸣器自动播放下一个音调。当按键B被长按时,就实现了旋律的连续播放。最终代码如下:
tone_list = [454,454,422,454,-1,358,-1,358,454,550,518,454,
358,358,326,358,-1,262,-1,262,358,454,422,358]
while True:
if cp.switch:
if cp.button_b:
cp.play_tone(tone_list[flag], 0.1)
flag = (flag + 1)%24
最终把两者结合起来,得到的主函数如下:
import time
import random
from adafruit_circuitplayground import cp
color_values = [0, 63, 127, 191, 255]
current_color = [255, 255, 255]
cp.pixels.brightness = 0.1
tone_list = [454,454,422,454,-1,358,-1,358,454,550,518,454,
358,358,326,358,-1,262,-1,262,358,454,422,358]
flag = 0
while True:
for i in range(10):
cp.pixels[i] = current_color
if cp.switch:
current_color = current_color
if cp.button_b:
cp.play_tone(tone_list[flag], 0.1)
current_color = change_color(current_color)
flag = (flag + 1)%24
else:
flag = 0
current_color = change_color(current_color)
cp.pixels.show()
time.sleep(0.1)
在视频演示中,我们可以看到,当拨动开关置右时,LED灯自动切换颜色;当拨动开关置左且按键B被按下时,LED灯手动切换颜色,同时蜂鸣器播放旋律。这一互动体验不仅增加了装饰的趣味性,也提升了用户的参与感。
视频演示见视频的后半部分。
[localvideo]d908620f4fca895e600c0b6d58d9868c[/localvideo]
- 2024-08-29
-
发表了主题帖:
【Follow me第二季第1期】 普通任务:光照传感器和温度传感器
本次测评的基础任务主要围绕几种传感器的运用,以实现对环境温度和光照的监测。
1. 基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
这个任务主要涉及温度和光照传感器的使用。
首先是光照传感器,使用方法可以参考教程Light模块【Light | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】,通过cp.light就可以读取光照传感器采集的数值。
此外,教程进一步提供了一个量化光照强度并转换为LED亮灯数量的函数示例,具体如下:
def scale_range(value):
return round(value /320*9)
此函数将传感器读数转换为0到9之间的整数,代表亮灯的数量。虽然直观,但我们将在后面的任务中探讨更优化的编写方法。
同时,教程中也提到,可以通过串口把光照传感器采集的数据发送给电脑,这对于后面任务中确定亮灯的阈值非常重要。这个操作也很简单,通过print(cp.light)就可以实现。
其次再看温度传感器,使用的方法和光照传感器是一样的,可以参考教程的Temperature部分【Temperature | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】,通过cp.temperature,我们获取了以摄氏度为单位的温度读数,如果是华氏度还需要自行换算。
同样地,为了量化温度读数,教程推荐了另一种方法,如下:
def scale_range(value):
return int((value - minimum_temp) / (maximum_temp - minimum_temp) *10)
这种方法不仅直观,而且具有更高的通用性和可复用性,便于迁移至其他传感器的应用。
回到实际的任务,我们先通过以下的代码,打印一下当前的光照强度和温度,作为我们设置的舒适温度的标准。
import time
from adafruit_circuitplayground import cp
while True:
print(cp.light)
print(cp.temperature)
time.sleep(1)
打开串口,输出如下:
可以看到光照强度大约是160左右,温度是26℃左右。基于此,我们设定了光照的上限为200,下限为100;温度的上限为30℃,下限为24℃。为了统一光照和温度的量化表示,我们对量化函数进行了如下优化:
def scale_range(value, minimum_value, maximum_value):
return min(int((value - minimum_value) / (maximum_value - minimum_value) * 5), 5)
实现对两个计算式的合并,分别用左右两侧各5盏LED来分别量化表示光照和温度。同时考虑到实际的采集值可能会超过我们设置的阈值,防止两边亮灯互相干扰,此函数限制了亮灯数量的最大值为5,确保了LED显示的一致性和直观性。
由于板子上的LED灯编号是按照逆时针编码的,我们用0-4来表示光照,5-9表示温度,光照从0开始依次点亮表示光照逐步增强;与之对称的,温度这一侧需要从9开始依次点亮表示温度增高,实际点灯的顺序与编号顺序相反。
为了方便每次亮灯的顺序,LED灯的状态更新通过编写专门的函数实现,该函数不仅考虑了LED灯的编号顺序,还通过颜色编码区分了不同的环境状态。光照部分都亮白灯;温度部分,适宜温度时亮绿灯,低于适宜温度时亮蓝灯,高于适宜温度时亮红灯,以示区别。更新LED状态的函数如下:
def update_leds(peak_light, peak_temp):
for i in range(10):
pixels[i] = (0, 0, 0)
for i in range(peak_light):
pixels[i] = (255, 255, 255)
if peak_temp < 3:
color = (0, 0, 255)
elif peak_temp == 3:
color = (0, 255, 0)
else:
color = (255, 0, 0)
for i in range(10 - peak_temp, 10):
pixels[i] = color
return pixels
最后在主循环中去调用这个更新LED状态的函数,将所有的灯按照更新好的状态点亮,完整的代码如下:
import time
from adafruit_circuitplayground import cp
cp.pixels.auto_write = False
cp.pixels.brightness = 0.1
minimum_light = 0
maximum_light = 200
minimum_temp = 25
maximum_temp = 32
pixels = [0] * 10
while True:
print((cp.light,cp.temperature))
peak_light = scale_range(cp.light, minimum_light, maximum_light)
peak_temp = scale_range(cp.temperature, minimum_temp, maximum_temp)
pixels = update_leds(peak_light, peak_temp)
for i in range(10):
cp.pixels[i] = pixels[i]
cp.pixels.show()
time.sleep(0.05)
我们可以看到左边的温度指示灯和右边的光照指示灯被点亮,视频中也演示了当用手指遮挡光线或者触碰温度传感器,改变光照强度和温度的时候,出现的指示灯数量变化。
视频演示见视频前半部分。
2. 基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
本任务旨在通过设定安全距离,并利用板载LED展示接近状态,同时在检测到入侵行为时发出声音报警。虽然红外传感器以其测量精度而广受推荐,但是翻遍了教程没找到红外传感器模块在哪里调用。虽说看到板子上有TX和RX两个IR的端口,但是例程中给出的似乎是使用他们来进行板间通信的。参考了一下其他朋友的设计报告,还是决定采用光照传感器来做。
我们的设计思路是通过固定光源照射开发板,并点亮板上所有LED灯来模拟环境光照。当物体接近时,会遮挡外部光源,导致光照传感器只能接收到来自板载LED的光,从而读数下降。相反,当物体非常接近时,其表面的反射作用会增强传感器的读数。基于这一原理,我们设定了当传感器读数异常升高时,触发蜂鸣器发出警报。
蜂鸣器的模块参考教程的Play Tone【Play Tone | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】和Play File【Play File | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】部分,无论是通过直接播放音调还是播放音频文件,蜂鸣器都能有效地发出警示声音。
为了深入理解不同距离对光照传感器读数的影响,我们编写了以下代码来记录和绘制光照强度的变化曲线:
import time
from adafruit_circuitplayground import cp
while True:
print((cp.light,))
time.sleep(0.1)
可以看到下图中分别对应正常的光照强度,有遮挡的光照强度,以及当遮挡物非常接近时的光照强度。
在无遮挡和正常遮挡的情况下,光照传感器的采样值相对比较稳定,分别是120左右和5左右。但是当物体非常接近时,尽管光照传感器采样值出现增大,最大值可以超过250。我们将250设置为安全距离,但是因为物体移动或者不平整等原因,导致比较大的波动,可能会出现一些误判断的情况。
我们根据实验数据设定了安全距离阈值为250。在无遮挡时,LED显示绿色;当物体遮挡但距离较远时,LED显示蓝色;而当物体非常接近时,LED显示红色,并触发蜂鸣器报警。以下是具体的代码实现:
import time
from adafruit_circuitplayground import cp
while True:
if cp.light < 140:
for i in range(10):
cp.pixels[i] = (0, 0, 255)
cp.pixels.show()
elif cp.light > 250:
for i in range(10):
cp.pixels[i] = (255, 0, 0)
cp.pixels.show()
cp.play_file("dip.wav")
else:
for i in range(10):
cp.pixels[i] = (0, 255, 0)
cp.pixels.show()
time.sleep(0.01)
实验结果显示,在物体遮挡光源但距离较远时,板载LED呈现蓝色;而在物体非常接近板子时,LED呈现红色,并伴有蜂鸣器的报警声。如下图所示:
当然我们采用硬纸板是可以反光的,从而使得非常接近板子的时候反而能加强光照传感器的读数。然而,对于非反光材料,这种监测方法可能不再适用。此外,由于物体遮挡和接近板子之间必然经过正常光照的中间状态,可能会导致在某些适中距离下出现误判。
尽管基于光照传感器的接近检测存在一定的局限性,但它为我们提供了一种低成本且易于实现的解决方案。未来,我们计划进一步研究如何有效利用红外模块,以提高接近检测的准确性和可靠性。
视频演示见视频地后半部分。
[localvideo]a55619fea3b5c33fe3db11cb7be302e2[/localvideo]
- 2024-08-27
-
发表了主题帖:
【Follow me第二季第1期】 入门任务:板载LED点亮以及跑马灯效果
本帖最后由 cyz6668 于 2024-8-27 00:40 编辑
很高兴参加本次的Follow me开发板体验活动,经过一系列的测评任务,我现在已经完成了对Adafruit开发板的初步探索,并准备整理实验结果和上传报告。
以下为记录完整的实验过程:
1. 开发板开箱:
收到的Adafruit开发板外观精美,配件齐全。
2. 入门任务(必做):开发环境搭建,板载LED点亮
我首先尝试了Makecode的图形化编程,但还是觉得代码编辑器的界面更加顺手一些,最终选择了CircuitPython作为开发语言,因为它提供了丰富的库支持和易于上手的特性。
按照提供的使用指南【Overview | Adafruit Circuit Playground Express | Adafruit Learning System】, 下载好了烧录所需的.uf2文件和CircuitPython固件库。如下:
通过双击开发板的Reset按钮,将开发板置于刷机状态。此时开发板亮起绿灯,电脑识别出新的驱动器CPLAYBOOT,这标志着连接成功。
将之前准备好的.uf2文件复制到驱动器中,等待一段时间,板子呈现红灯全亮的状态,并且之前的驱动器弹出并且重新被识别为CIRCUITPY,即可烧录Python程序。
将下载好的固件库复制到板子中,这些都是Circuit Playground Library中的函数,提供了各种功能和参考例程,只是很多在这次任务中暂时使用不到,等后面会继续研究。
看了一下教程提供的例程代码,好像是有两种不同的调用库函数方式,看到有直接import board,import digitalio这样调用板子不同的输入输出端口或者外设的;也有用from adafruit_circuitplayground import cp,用cp.XX来调用外设的。个人理解上有点像后一种是又额外封装了一层库函数,参考这个CircuitPython Made Easy【Circuit Playground Library | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】
我更倾向于使用后者,因为它提供了更简洁的封装。后续的任务都会基于此,也就是Circuit Playground Library的库函数来进行完成了,两者本质上区别并不大。
板子适配好以后,安装CircuitPython的编译器Mu Editor,在模式中选择CircuitPython,就可以进行代码的编写和烧录。
最简单的点亮板载LED的代码,参考教程中的Red LED【Red LED | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】,将cp.red_led置1即可点亮,代码如下:
from adafruit_circuitplayground import cp
while True:
cp.red_led = True
实现板载LED灯的点亮效果如下,可以看到D13位置的LED灯点亮:
视频演示见视频前半部分。
3. 基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
这部分任务需要使用到板子外围的一圈LED灯,并且依次去点亮并赋予不同的颜色。参考教程的NeoPixels部分【NeoPixels | CircuitPython Made Easy on Circuit Playground Express and Bluefruit | Adafruit Learning System】,我们可以知道使用如下代码可以亮灯:
cp.pixels[i] = (R,G,B)
其中i表示需要点亮的LED灯的编号,三元数组(R,G,B)用于设置灯的颜色。
为了方便实现跑马灯的颜色变换,我们预先设置了一个颜色的列表color,用于存储可能用到的颜色,然后只需要每一盏灯按顺序依次取一种颜色即可,超过取色的列表范围就从头开始取。同时在每一次循环中,LED灯的起始颜色会更新为颜色列表中的下一个颜色,这样,整个LED灯带就会呈现出流动的光效。
代码如下:
from adafruit_circuitplayground import cp
cp.pixels.brightness = 0.1
num_pixels = 10
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255),
(0, 255, 255), (255, 127, 0), (127, 255, 0), (127, 0, 255), (0, 127, 255)]
while True:
for i in range(num_pixels):
start_color = i
for j in range(num_pixels):
cp.pixels[j] = colors[(i+j)%10]
可以看到板上的LED呈现出不同的颜色,如下:
视频演示见视频后半部分,可以看到颜色的变化和流动的效果。
[localvideo]3926d40a5dd4931e5e9e5a377f35864e[/localvideo]