K10
## 概述
这次的行空板K10板子,内核心是ESP32S3,性能不错,官方配套的Mind+(UNIHIKER-K10-200902)开发工具,还提供了二维码识别、语音合成等多项功能,经过一番研究,制作了这个二维码音乐播放器,分享给大家。
在具体实现的过程中,得到了 **DFRobot技术大佬 @柳春晓** 的大力帮助,特此感谢!

这个行空板K10二维码音乐播放器,具体使用到了K10和Mind+的屏幕显示、二维码扫描、麦克风数据读取、SD卡图片显示、SD卡音频文件播放、语音合成、串口输出等多项具体的功能,非常具有学习的价值。
下面就是具体的实现过程。
### 规划和实现的基本功能如下:
1. 开机进入播放器扫码界面
2. 扫码成功后,进入播放对应歌曲的页面
3. 操作过程,用语音提示
4. 音乐文件和图片文件,都放置在SD卡上,方便扩展
### 要完成上述功能,需要进行如下的工作:
1. 逻辑流程设计
2. 硬件准备
3. 歌曲整理
4. 歌曲图片设计
5. 播放器界面设计
6. 二维码设计
7. 程序设计
步骤1 ## 逻辑流程设计
根据我的预想规划,设计了如下的流程图:

在实际制作的过程中,上面的流程图也经过了逐步的完善。
其中,各块的作用如下:
1. `主逻辑区块`:程序主流程部分
2. `函数:二维码获取歌曲信息并播放`:负责扫码检测和播放歌曲
3. `函数:识别结果解析`:负责从扫码结果解析信息
4. `函数:从字符串获取信息`:负责从字符串中提取子字符串
5. `函数:麦克风静音检查`:负责检测麦克风
步骤2 ## 硬件准备
核心是咱们的行空板K10:

再准备一张SD卡即可。注意,SD卡需要格式化为FAT32格式,才可以被正确读取内容。
在SD卡上,要准备如下的目录:
* S:/p_images/:存放播放器界面文件
* S:/m_images/:存文歌曲图片文件
* S:/music/:存放歌曲音频文件
步骤3 ## 歌曲整理
歌曲可以根据实际的需要进行整理。
因为我用的二维码设计工具,一张纸可以打印12各二维码,所以我准备了12首儿歌进行测试。
具体歌曲如下:
```
1 ABCD字母歌.wav
2 Bingo.wav
3 一分钱.wav
4 三字经.wav
5 上学歌.wav
6 丢手绢.wav
7 健康歌.wav
8 凤尾草.wav
9 刷牙歌.wav
10 卖报歌.wav
11 卖汤圆.wav
12 娃哈哈.wav
```
将歌曲按照序号保存为:1.wav 2.wav...并存到SD卡的 /music/ 目录中:

步骤4 歌曲图片设计
在播放时,为了更好的界面显示,我给每一首歌曲设计了一张简洁的图片,用于播放时显示,具体样式如下:

将每一首歌的图片设计好,并按照序号保存,12首歌的所有图片如下:

将上述图片,存储到 SD卡 的 /m_images/ 目录中。
步骤5 ## 播放器界面设计
一开始制作的时候,我直接在屏幕上显示文字,来表示当前的界面。
后来,歌曲图片也设计了,直接显示文字就不美观了,于是设计了专门的播放器首界面和扫码界面,具体如下。
首界面:

扫码界面:

这个扫码界面上部的白色区域,是透明的,从而可以在这个区域,显示出来摄像头拍摄的画面,方便对准二维码。
最开始设计扫码界面的时候,测试过把切分图片为小区块,白色区域的图片不显示,一遍摄像头界面可以呈现。
后来经过测试,发现保持透明通道PNG图片,其透明区域,不会覆盖下一层的内容,从而可以正常显示摄像头的画面。
步骤6 二维码设计
前面把歌曲名称、歌曲图片、歌曲音频文件都准备好了,下一步就是用二维码把他们和程序关联起来。
二维码设计平台,我使用的是草料二维码:[https://cli.im/](https://cli.im/),非常好用。
具体设计的样式如下:

然后批量生成二维码:

每个二维码对应的具体信息格式如下:`歌曲序号,歌曲音频文件;歌曲图片文件:歌曲名称`
在程序中,我编写了专门的函数,来从里面提取出来所需要的歌曲信息。
最后,下载生成的二维码对应的PDF文件:

实际得到的文件内容如下:

可以把上述二维码打印出来,然后裁剪开来,把每一个二维码分散贴到墙上或者需要地方。
在实际识别的时候,二维码不要太集中,否则无法正确识别,K10目前也不支持多个二维码识别处理。
步骤7 ## 程序设计
万事俱备,只欠东风,最关键的部分,就是程序设计了。
DFrobot提供的Mind+开发界面,还是非常好用的,在做好了逻辑流程设计的前提下,开发速度还是很快的。
根据逻辑流程设计,分别开发了如下的程序区块。
### 主逻辑区块

这个区块的逻辑比较简单:
1. 设置串口、语音速度、屏幕方向参数。
2. 清屏,显示播放器首界面
3. 清屏,显示摄像头画面,并切换到二维码识别模式
4. 显示播放其扫码界面
5. 最后,在循环中,调用`函数:二维码获取歌曲信息并播放`
6. 中间在适当的位置,复制语音提醒
### 函数:二维码获取歌曲信息并播放

这个部分的逻辑,稍微复杂一些,具体如下:
1. 检测是否扫描到二维码
2. 如果二维码包含了.wav,则认为扫描正确
3. 调用`函数:识别结果解析`,来获取歌曲信息
4. 清屏,显示当前需要播放的歌曲图片
5. 播放歌曲对应的音频文件
6. 调用`函数:麦克风静音检查`
7. 播放完毕后,上述调用退出,再次显示扫码界面
8. 适当的时候,使用串口输出和语音提醒
### 函数:识别结果解析

这个部分的逻辑,也较为简单,主要就是调用`函数:从字符串获取信息`,从而得到歌曲序号、歌曲音频文件、歌曲图片文件、歌曲名称的信息,然后再生成歌曲路径、图片路径备用。
在调用`函数:从字符串获取信息` 时,会传入对应的参数表示一个信息的开始和结尾。
这个与二维码信息格式保持一致即可:`歌曲序号,歌曲音频文件;歌曲图片文件:歌曲名称`
另外,如果时开头,则用`^`表示,如果是结尾,则用`$`表示。
### 函数:从字符串获取信息

这个部分的功能,一开始时使用内置的积木块:
目前版本的Mind+(UNIHIKER-K10-200902),该积木块的功能还存在问题,所以自己写了一个调用函数。
其具体功能,就是循环字符串的每一个字符,通过首尾字符,判断是否开始和结束提取字符,如果需要提取字符,则将其内容合并到`字符处理结果`中,循环完毕,就能在`字符处理结果`中得到需要的字符子串了。
### 函数:麦克风静音检查

这个部分的功能,用于通过麦克风,来检测歌曲播放是否结束。
目前版本的Mind+(UNIHIKER-K10-200902),歌曲播放的时候没有标志信息,不知道什么时候已经播放完毕。
因此,通过K10板载的麦克风,来检测音量。如果音量低于指定的阈值,达到一定的次数,则认为播放完毕。
具体逻辑可见前面的流程图。
需要注意的是,这个检测并不总是准确,环境声音会影响检测,同时,你也要根据你的实际情况,调整传入的音量阈值。
**DFRobot技术大佬 @柳春晓** 说后续版本,将会提供播放标志,这样就能很方便的判断了。
### 完整程序
最终,完整的程序如下:
以上各区块的逻辑,可以对照前面的流程图查看了解。
正常编译烧录后,就可以进行运行测试了。记住要先把SD卡给插上!
步骤8 实测
这是最激动人心的环节,辛苦了好几天,就看最后的成果了。
### 开机画面

### 二维码扫描界面


### 播放界面

### 视频
实际效果还是很不错的,下面看一下视频:
rzyzzxw2024.11.16
太厉害了