寒假在家一起练(1) - 制作一个音乐播放器项目介绍
制作一个音乐播放器:利用板上的无源蜂鸣器,播放一首音乐,并通过加入 LED 闪烁的效果,增加观赏性和趣味性,做出声光具备的作品。
一、设计思路
利用 PWM 生成不同频率,持续时间不同的音调,驱动蜂鸣器播放音乐,程序中制作一个标准的音符库,播放音乐的时候通过查找表的方式把该音符对应的频率的信号播放出来,加入 LED 灯随节拍闪烁。
脉冲宽度调制(PWM),是英文“Pulse Width Modulation"的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM的控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率。其中,一个周期内脉冲时间占总时间的比值称为占空比。
无源蜂鸣器利用电磁感应原理,为音圈接入交变电流后形成的电磁和永磁铁相斥而推动振膜发声,无源蜂鸣器的内部不带振荡源,通过使用50%占空比的500Hz~4.5kHz频率的PWM波驱动,就可以播放出不同音调的声音。
首先在需要制作一个标准的音符库,不同的音符对应一个指定的 PWM 频率,然后输入想要播放音乐的曲谱,这样就可以对曲谱的音符逐个分析,通过查表的方法,将每一个音符输出为对应的 PWM 频率,从而驱动无源蜂鸣器发出正确的声音,并且可以通过更改 PWM 的占空比来控制无源蜂鸣器的声音大小。LED 随音乐闪烁的效果可以通过每次查表输出对应的 PWM 波后,反转 LED 的控制引脚即可实现。
二、流程图
三、硬件介绍
基于树莓派Pico的嵌入式系统学习平台,专为嵌入式系统学习而设计,其可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用。
平台包含:
-
树莓派Pico扩展板 x1
-
硬禾版本树莓派Pico核心模块 - STEP Pico x1
-
Type-C 数据线 x1
硬禾版本树莓派Pico核心模块与树莓派官方Pico是相互兼容的,并且在其基础上增加了4个WS2812彩色灯,以及一个复位按键,USB端口也改成了Type C,使用体验大幅提升。
树莓派Pico扩展板还带有以下外设:
-
2个按键输入
-
4个单色LED
-
12个WS2812B RGB三色灯
-
1个姿态传感器
-
1个128*64 OLED显示屏
-
1个蜂鸣器
-
1个可调电位计(用于电压表)
-
1路音频信号输入(用于示波器)
-
8位R-2R电阻网络构成的DAC(用于DDS信号发生器)
完全足够我们进行一些有趣的小项目的开发。并且由于支持MicroPython,手上使用也是非常的容易,对于新手来说十分的友好。
四、实现功能展示
利用板上的无源蜂鸣器,播放音乐《我是一个粉刷匠》,并通过加入 LED 闪烁的效果,增加观赏性和趣味性,做出声光具备的作品。
完整的实现功能展示可以查看该视频:寒假一起练 制作一个音乐播放器
遇到的主要难题和解决办法
这次是我第一次尝试使用MicroPython对树莓派Pico进行开发,所以在开发之初是有点无从下手的,首先搭建环境就遇到了一些问题。
我选择的是VScode中的RT-Thread MicroPython插件进行开发,在 windows 操作系统下使用插件需要将 vscode 的默认终端修改为 powershell。
MicroPython 开发的第一步是创建 MicroPython 工程,后续所有操作都必须在工程内才能运行。创建一个新的 MicroPython 工程有两种方式,分别是创建一个空白工程和基于 Demo 创建工程。连接开发板,点击左下角的连接按钮,然后在弹出的设备列表中选择想要连接的设备,即可连接 MicroPython 开发板。在开发板上运行 MicroPython 代码片段:如果只是想进行代码量不大的代码调试,而不想将文件下载到开发板上,那么可以使用代码片段功能。在编辑器中选中想要运行的代码片段,然后在右键下拉菜单中选择 在设备上执行选中的 MicroPython 代码
选项,即可在 REPL 环境中运行所选代码。
该插件的功能非常强大,但是在一开始我并不知道该怎么具体使用,后来才知道,需要先去到Micropython的官网,下载对应的Pico固件,并加载到Pico中去,才能使用该插件进行连接和开发。
并且在开发的过程中,我先分别实现了对WS2812B RGB三色灯和无源蜂鸣器的控制,但将这两个项目合并到一起时却遇到了难题,我想要通过多线程的方式将两个项目合并到一起同时运行,但是在网上查阅了关于Pico MicroPython的多线程控制,尝试后均以失败告终,最后无奈,只能将RGB换为简单的LED控制。
五、代码片段解释
# 定义音调频率
#制作一个标准的音符库,不同的音符对应一个指定的 PWM 频率
tones = {'1': 262, '2': 294, '3': 330, '4': 349, '5': 392, '6': 440, '7': 494, '-': 0}
# 定义旋律,根据制作的音符库存储音乐的曲谱
melody = "5353531-24325--5353531-24321--2244315-24325--5353531-243210"
#通过查表的方法,将每一个音符输出为对应的 PWM 频率,从而驱动无源蜂鸣器发出正确的声音
for tone in melody:
freq = tones[tone]
if freq:
beeper.duty_ns(20000)
beeper.freq(freq) # 调整PWM的频率,使其发出指定的音调
else:
beeper.duty_ns(0) # 空拍时一样不上电
六、未来的计划和建议
为了在规定的时间内完成项目,MicroPython下多线程的问题并没有解决,只是替换为更简单的方案,后续希望继续对MicroPython下的多线程进行研究。