【Follow me第二季第1期】+作业提交+显眼包胸章
[复制链接]
本帖最后由 sipower 于 2024-10-9 21:17 编辑
【Follow me第二季第1期】+作业提交+显眼包胸章
视频展示:
在发完开箱贴后,一直断断续续完成作业,中间没有时间再单独发帖,索性这次任务做完,一帖全搞定。
下图是从得捷购买并用到的器件:
开箱贴:
首先是按要求完成任务。由于我比较喜欢circuitpython这种不用编译,运行所见即所得的开发方式,所以这次任务全部由circuitpython代码完成。
- 入门任务(必做):开发环境搭建,板载LED点亮
这个任务最简单了,上期比赛就用过circuitpython,环境是现成的,我比较喜欢Thonny的编辑界面,感觉Mu编辑器界面比较繁琐。下图是代码,几行语句就实现了。
点亮LED的效果如下图。
2、基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换
这个任务使用rainbowio库里的colorwheel函数,我先定义一个跑马灯函数,然后主循环根据自己喜好控制延时,不停调用即可,代码如下图。
演示效果见开头视频。
3、基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度
这个任务使用adafruit_circuitplayground的库函数可以获取温度值和光照强度,然后我设计一个程序,实现如下功能:
环境光亮度转换成十个灯的光轮,环境光越亮,点亮灯珠越多。温度舒适用颜色表示,在24-27摄氏度之间用绿色,小于24摄氏度用蓝色,大于27摄氏度用红色。
代码如下图:
演示效果见开头视频。
4、基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警
这个任务难度主要在于板载红外传感器的电压检测。在官方网页中并没有详细提到如何通过模拟方式检测红外输出电压,例程也只有数字信号检测。后来我在官方网站找到了原理图,是我没用过的EagleCAD格式的,好在经过一番摸索,发现可以用立创EDA在线打开,我索性导出一版图片格式原理图,如下图。
从原理图上可以看到,红外传感器除了输出数字信号外,还有一路模拟信号接入单片机,在circuitpython系统中定义是:board.IR_PROXIMITY,有了这个设置,后面只需按照模拟量采集处理就行了。我设计的程序功能如下:
红外发光管采用闪烁方式发光,避免过热烧毁。被测物体会反射红外光,根据距离反射的强度不一样,这样红外传感器输出电压也随距离变化。RGB灯设置成距离越近,亮的数量越多,颜色由远处是绿色,逐渐变成橙色,最近处变成红色。同时让蜂鸣器发声,频率也设置成距离越近越高,显得更急促,有点倒车雷达那个感觉。代码如下。
演示效果见开头视频。
5、进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果
由于adafruit_circuitplayground的库函数有现成的加速度传感器接口供调用,这个任务也比较简单,我这里设计程序,把加速度三个轴的绝对值和R、G、B三个基本颜色做了关联,不倒翁晃动的时候,就会变幻不同颜色。当绝对值大于特定值时,还让蜂鸣器发声,显得更有趣。代码如下图。
演示效果见开头视频。
6、创意任务三:水果钢琴——通过触摸水果弹奏音乐,并配合灯光效果
创意任务我选了这个,同时也是为我的终极任务做准备。这个任务也比较简单,直接调用adafruit_circuitplayground的库函数中现成的触摸按键库,再配合触摸按键邻近的RGB灯即可实现,代码如下。
演示效果见开头视频。
仅仅使用开发板自带的蜂鸣器发音,那声音效果太单薄了,我还配套买了DFR0534和小喇叭,必须用起来。DFR0534是串口控制的音乐播放小板,可以播放内置存储的MP3和WAV格式的音频,在开箱贴有详细介绍,这里不赘述。首先是把这些器件连接起来,效果如下图。
然后在DFR0534中存上音频,如下图。
其中,音频01-07分别对应do、re、mi、fa、sol、la、si七个音符。
通过使用串口发指令,可以让DFR0534播放指定的音频。我给DFR0534做了一个库,代码见文末代码包。由于串口TX和RX占用了2个触摸按键,最终可触摸的只剩5个,实现功能大致和上个相同,代码如下图。
演示效果见开头视频。
7、终极任务---显眼包胸章
我的终极创意任务是做一个显眼包胸章。利用本板卡制作一个胸章,主要给孩子佩戴,晚上带孩子逛公园,小孩乱跑,照明不太好的情况,不好跟踪小孩位置,给他戴上这个胸章后,由于有RGB灯发光,就容易找到孩子位置。晚上戴这个炫酷胸章出门,小孩肯定会成为公园最亮的仔。
目前实现了以下功能:实时检测环境音量,根据音量控制RGB灯环闪烁变色,声音越大,点亮的灯珠越多。还可以触摸按键,双击动作触发音频播放,提示家长关注孩子状态。本来还想添加更多功能,比如根据动作展示不同的灯光秀,动作控制声音等,由于内存限制,未能添加上,比较遗憾。
下面是设计过程。
先是用亚克力板根据Adafruit Circuit Playground Express轮廓切了两个圆片,它们之间用铜柱固定,如下图。
然后给音频模块焊上自制的连接触环,这个触环使用插母的金属片打制,导电效果不错。小喇叭是用热熔胶粘在音频板上的,将线缆尽可能窝在一起节省空间。如下图。
然后将它们叠拼组装到一起,使用铜柱和螺丝拧紧,其中铜柱将触环压在Adafruit Circuit Playground Express焊盘上,起到连通电路的作用。如下图。
最后在背面粘上一块扁平的聚合物电池,成品就完成了,如下图。
作品代码如下,其中注释掉的部分代码就是因为内存不够。只好舍弃的功能。
代码1
import time
import array
import math
import audiobusio
import board
import busio
import dfr0534
from adafruit_circuitplayground import cp
cp.pixels.fill((0, 0, 0)) #关掉所有RGB灯,防止晃眼睛
# Change to 1 for single-tap detection.
cp.detect_taps = 2
uart = busio.UART(board.TX, board.RX, baudrate=9600, timeout=1)
# dataIn1 = 55
mp3 = dfr0534.MP3(uart)
mp3.volume(value=80)
# dataIn1 = mp3.query_play_status() #查询播放状态
# print(dataIn1)
# Color of the peak pixel.
PEAK_COLOR = (100, 0, 255)
# Number of total pixels - 10 build into Circuit Playground
NUM_PIXELS = 10
# Exponential scaling factor.
# Should probably be in range -10 .. 10 to be reasonable.
CURVE = 2
SCALE_EXPONENT = math.pow(10, CURVE * -0.1)
# Number of samples to read at once.
NUM_SAMPLES = 160
# Restrict value to be between floor and ceiling.
def constrain(value, floor, ceiling):
return max(floor, min(value, ceiling))
# Scale input_value between output_min and output_max, exponentially.
def log_scale(input_value, input_min, input_max, output_min, output_max):
normalized_input_value = (input_value - input_min) / \
(input_max - input_min)
return output_min + \
math.pow(normalized_input_value, SCALE_EXPONENT) \
* (output_max - output_min)
# Remove DC bias before computing RMS.
def normalized_rms(values):
minbuf = int(mean(values))
samples_sum = sum(
float(sample - minbuf) * (sample - minbuf)
for sample in values
)
return math.sqrt(samples_sum / len(values))
def mean(values):
return sum(values) / len(values)
def volume_color(volume):
return volume * (255 // 10), 50, 0
# Main program
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
sample_rate=16000, bit_depth=16)
# Record an initial sample to calibrate. Assume it's quiet when we start.
samples = array.array('H', [0] * NUM_SAMPLES)
mic.record(samples, len(samples))
# Set lowest level to expect, plus a little.
# input_floor = normalized_rms(samples) + 10
# OR: used a fixed floor
input_floor = 50
# You might want to print the input_floor to help adjust other values.
# print(input_floor)
# Corresponds to sensitivity: lower means more pixels light up with lower sound
# Adjust this as you see fit.
input_ceiling = input_floor + 500
peak = 0
while True:
mic.record(samples, len(samples))
magnitude = normalized_rms(samples)
# You might want to print this to see the values.
# print(magnitude)
# Compute scaled logarithmic reading in the range 0 to NUM_PIXELS
c = log_scale(constrain(magnitude, input_floor, input_ceiling),
input_floor, input_ceiling, 0, NUM_PIXELS)
# Light up pixels that are below the scaled and interpolated magnitude.
cp.pixels.fill((0, 0, 0)) #pixels.fill(0)
for i in range(NUM_PIXELS):
if i < c:
cp.pixels[i] = volume_color(i)
# Light up the peak pixel and animate it slowly dropping.
if c >= peak:
peak = min(c, NUM_PIXELS - 1)
elif peak > 0:
peak = peak - 1
if peak > 0:
cp.pixels[int(peak)] = PEAK_COLOR
cp.pixels.show()
#######################################################
if cp.tapped:
mp3.playList(19)
# print("Tapped!")
# if cp.shake(shake_threshold=20):
# mp3.playList(9)
# print("Shake detected!")
#######################################################
if cp.touch_A1:
mp3.playList(10)
# print("A1")
elif cp.touch_A2:
mp3.playList(11)
# print("A2")
elif cp.touch_A3:
mp3.playList(12)
print("A3")
# elif cp.touch_A4:
# mp3.playList(13)
# print("A4")
# elif cp.touch_A5:
# mp3.playList(14)
# # print("A5")
8、心得体会
本次活动任务难度系数不大,有adafruit_circuitplayground提供的库做基础,各种应用可以轻松实现。本次这个开发板可玩性很高,具备极大的趣味性,我在开发过程中,还不停的给孩子展示各个小效果,有些创意也让他一起参与进来,感觉既能熏陶的他兴趣,还能扩展知识面,接下来鼓励孩子使用微软的make code自己尝试编程,算是作为STEAM教育的入门课程吧。希望论坛以后多多选用类似板卡做活动,不但让我们工程师玩的飞起,还能培养下一代。
code.zip
(6.51 KB, 下载次数: 2)
|