1. 项目缘起:从“会说话的板子”到“能对话的伙伴”
几年前,我第一次把一块Micro:bit开发板递到一个孩子手里,他摆弄着上面的LED阵列,兴奋地按着按钮,但没过多久,新鲜感就褪去了。他问我:“老师,它除了亮灯和显示字母,还能做什么?它能听懂我说话吗?” 这个问题让我意识到,对于现在的孩子来说,交互的“智能感”远比简单的输入输出更有吸引力。一块能听会说、能根据指令做出反应的“板子”,才更像他们想象中的“机器人”。
这就是我们这次要做的“智能伴读机器人”项目的起点。它不是一个复杂的工业机器人,而是一个基于Micro:bit、结合语音识别与合成技术,能与孩子进行简单语音交互的创意伙伴。你可以把它想象成一个会讲故事的“电子宠物”,或者一个能陪你背单词的“学习伙伴”。它的核心目标,是让编程和硬件学习变得更有温度、更互动。我们不再仅仅学习如何让LED闪烁,而是学习如何让硬件“听懂”我们的指令,并用“声音”回应我们,从而构建一个完整的、有反馈的交互闭环。
这个项目将涉及几个关键技术点:如何让Micro:bit“听见”声音(语音识别),如何让它“说出”话来(语音合成),以及如何设计一个逻辑清晰的程序(列表管理)来协调这两者,实现诸如“点播故事”、“问答互动”等功能。整个过程,我们会从最基础的硬件连接讲起,深入到代码逻辑的每一个细节,并分享我在实际教学中遇到的真实问题和解决方案。无论你是教育工作者、家长,还是对硬件和AI交互感兴趣的爱好者,跟着这篇长文一步步操作,你都能亲手打造出这个充满趣味的智能小装置。
2. 硬件选型与连接:构建机器人的“感官”与“声带”
一个智能伴读机器人,首先需要“耳朵”和“嘴巴”。Micro:bit本身没有麦克风和扬声器,所以我们需要为它扩展这些能力。市面上相关的模块很多,选择哪一套组合,直接关系到项目的成本、复杂度和最终效果。
2.1 核心模块选型:为什么是Gravity系列?
经过多次项目实践,我强烈推荐使用DFRobot的Gravity系列传感器模块。原因有三:第一,接口标准化,PH2.0-3P接口防反插,对新手极其友好,大大降低了接错线烧坏元件的风险;第二,配套的Mind+或MakeCode图形化/代码编程平台支持良好,有丰富的示例库;第三,社区资源丰富,遇到问题容易找到解决方案。
对于本项目,我们需要两个核心模块:
- 语音识别模块:这里我选用Gravity: 离线语音识别传感器(I2C & UART)。注意,一定要选择“离线”版本。在线语音识别(如调用百度、科大讯飞API)需要联网,增加了复杂性和不确定性。离线模块内置了语音识别芯片,本地处理指令,响应速度快,且不依赖网络,稳定性极高。它支持通过I2C或UART与Micro:bit通信,我们通常使用更简单的I2C接口。
- 语音合成模块:这里我选用Gravity: 中英文语音合成模块(UART)。这个模块可以将我们发送的文本转换成清晰、自然的中文或英文语音播放出来。它通过UART(串口)与Micro:bit通信。
注意:务必确认模块版本。早期的一些语音合成模块可能需要额外的功放电路和喇叭,而现在的Gravity语音合成模块通常集成了功放,可以直接连接一个8Ω 1W-2W的小喇叭。购买时请查看商品详情。
2.2 硬件连接图与接线逻辑
连接是硬件项目的第一步,也是新手最容易出错的地方。下面这张表格清晰地展示了如何将Micro:bit、语音识别模块和语音合成模块连接起来:
| 模块 | 接口线 | 连接到 Micro:bit 扩展板引脚 | 功能说明 |
|---|---|---|---|
| 语音识别模块 | SDA (数据线) | P20 | I2C通信的数据线 |
| SCL (时钟线) | P19 | I2C通信的时钟线 | |
| VCC (电源正极) | 3.3V | 重要!必须接3.3V,接5V可能损坏模块 | |
| GND (电源负极) | GND | 共地,提供电流回路 | |
| 语音合成模块 | RX (接收端) | P1 (TX) | 模块的RX接Micro:bit的TX(发送端) |
| TX (发送端) | P2 (RX) | 模块的TX接Micro:bit的RX(接收端) | |
| VCC (电源正极) | 5V | 语音合成模块通常需要5V供电以获得足够音量 | |
| GND (电源负极) | GND | 共地 |
接线实操心得与避坑指南:
- 电源电压是关键:语音识别模块的芯片工作电压往往是3.3V,所以必须接3.3V引脚。而语音合成模块的功放部分需要更高电压驱动喇叭,所以接5V。接反电压是烧毁模块最常见的原因,没有之一。
- 串口交叉连接:记住一个原则:发送端(TX)永远连接接收端(RX)。Micro:bit的P1引脚在串口通信中默认为TX(发送),所以它应该连接到语音合成模块的RX(接收)。同理,Micro:bit的P2是RX,接模块的TX。如果接反了,数据无法传输,模块会毫无反应。
- 共地是必须的:所有模块的GND必须连接到Micro:bit扩展板的GND引脚。这确保了所有设备有一个共同的参考零电位,信号才能被正确识别。
- 先接线,后上电:养成好习惯,在所有连接确认无误后,再给Micro:bit上电(通过USB线连接电脑或电池盒)。
连接完成后,你的硬件系统就准备好了。接下来,我们将进入核心环节——编程,让这些硬件“活”起来。
3. 软件环境搭建与基础通信测试
硬件搭好了,就像给机器人装上了耳朵和嘴巴,但还没告诉它怎么听、怎么说。我们需要通过编程来建立通信规则。对于Micro:bit,MakeCode图形化编程环境是最佳起点,它直观且功能强大,足够完成我们这个项目。
3.1 初始化与“握手”测试
在编写复杂功能前,必须确保Micro:bit能分别与两个模块正常通信。我们分两步进行。
第一步:测试语音合成模块(让机器人“开口”)语音合成模块通过串口接收指令。指令格式通常是固定的帧结构,例如[0xFD, 0x00, 0x00, 0x01, 0x00, ‘H’, ‘i’]这样的十六进制数组,意思是合成播放“Hi”。但手动组帧非常麻烦。
实操技巧:在MakeCode中,我们使用一个现成的扩展库来简化操作。点击“扩展”,搜索“dfrobot-serial-voice-synthesis”并添加。添加后,你会发现积木区多了一个“语音合成”类别。里面有一个至关重要的积木:设置语音合成模块接收端为 RX P2 发送端为 TX P1 波特率 9600。这个积木必须在程序一开始就执行,它完成了串口的初始化和参数配置。
测试程序可以非常简单:
当开机时 设置语音合成模块接收端为 RX P2 发送端为 TX P1 波特率 9600 暂停(100)毫秒 // 给模块一点启动时间 语音合成播放“你好,世界!”下载到Micro:bit,如果听到清晰的“你好,世界!”,恭喜你,机器人的“声带”工作正常。
第二步:测试语音识别模块(让机器人“聆听”)语音识别模块通过I2C通信。同样,我们需要添加扩展库。搜索“grove”或“voice recognition”,找到类似“Grove - Voice Recognizer”的扩展并添加。
初始化积木可能是Voice recognizer set port (P20)(P19),这指定了I2C的SDA和SCL引脚。模块上通常有1-3个按键,用于录制和训练自定义指令。模块出厂可能预置了一些通用指令(如“开灯”、“关灯”),我们可以先测试这些。
测试程序:
当开机时 Voice recognizer set port (P20)(P19) 暂停(2000)毫秒 // I2C模块启动需要更长时间 无限循环 如果 Voice recognizer read result command 那么 显示图标 √ 暂停(100)毫秒 显示图标 X对着模块说出预置的指令词(如“开灯”),如果Micro:bit的LED点阵显示对勾(√)然后叉号(X),说明识别成功,通信正常。
常见问题排查:如果测试没反应,第一检查接线(特别是电源电压),第二检查扩展库是否正确添加,第三尝试增加初始化后的暂停时间。I2C设备对时序敏感,启动时间不足是常见问题。
4. 核心逻辑实现:列表管理与交互状态机
两个模块单独测试通过,只是万里长征第一步。真正的挑战在于如何将它们协调起来,实现一个流畅的“听-思考-说”的交互流程。这里,列表(List)和状态机(State Machine)的思想将成为我们程序的核心骨架。
4.1 为什么是列表?构建机器人的“记忆库”
伴读机器人需要存储和管理多个故事、诗歌或问答对。在编程中,管理一系列同类数据的最佳数据结构就是列表。我们可以把列表想象成一个个编号的储物格。
例如,我们要存储三个故事:
- 列表
故事标题= [“三只小猪”, “龟兔赛跑”, “乌鸦喝水”] - 列表
故事内容= [“从前有三只小猪...”, “兔子嘲笑乌龟爬得慢...”, “一只乌鸦口渴了...”]
这两个列表通过索引关联起来。索引就是储物格的编号,在MakeCode和大多数编程语言中,索引从0开始。所以“三只小猪”的索引是0,它的内容就在故事内容[0]里。
高级技巧:列表切片与随机选择如果我们想让机器人随机讲一个故事,就需要用到随机数和列表取值。
让 随机索引 为 在 0 到 (列表“故事标题”的长度 - 1) 之间取随机数 要播放的标题 = 列表“故事标题”中获取第 (随机索引) 项 要播放的内容 = 列表“故事内容”中获取第 (随机索引) 项 语音合成播放(连接“现在播放:”和要播放的标题) 语音合成播放(要播放的内容)这里,列表的长度是一个重要属性。故事标题列表有3项,长度就是3。随机数范围是0到2(因为3-1=2),正好覆盖所有有效索引。这就是一个完整的“随机点播”逻辑。
4.2 设计交互状态机:让对话有条不紊
机器人不能同时做所有事情。它应该处于不同的“状态”,例如“待机聆听状态”、“播放故事状态”、“问答状态”。这就是状态机思想:程序在任何时刻只处于一个确定状态,根据输入(语音指令)切换到下一个状态。
我们来设计一个简单的状态机:
- 状态0:待机状态。LED显示一个笑脸。在此状态下,它监听特定指令。
- 状态1:故事点播模式。当识别到指令“讲故事”后,进入此状态。LED显示“S”。在此状态下,它监听具体故事名,如“第一个故事”。
- 状态2:播放中状态。开始播放语音,LED显示滚动动画。在此状态下,暂时不听新指令,直到播放完毕自动回到状态0。
在MakeCode中,我们可以用一个变量当前状态来记录状态。
当开机时 设置变量`当前状态`为0 //待机状态 初始化语音合成与识别模块 无限循环 如果 `当前状态` = 0 那么 显示图标 ☺ 如果 语音识别到“讲故事” 那么 设置变量`当前状态`为 1 语音合成播放“请告诉我你想听第几个故事” 否则 如果 `当前状态` = 1 那么 显示字母“S” 如果 语音识别到“第一个” 那么 设置变量`当前状态`为 2 语音合成播放 列表“故事内容”[0] 等待播放完成 // 这是一个关键点,见下文 设置变量`当前状态`为 0这个框架清晰地将不同的交互阶段分隔开,避免了逻辑混乱。比如,在播放故事时(状态2),即使误识别到其他指令,也不会打断播放,因为程序逻辑当前不在状态0或1的判断分支里。
实操中的大坑:如何“等待播放完成”?MakeCode的语音合成播放积木是非阻塞的。意思是,它发出播放指令后立即执行下一行代码,不会等待语音说完。如果我们不处理,就会出现故事还没讲完,状态就跳回0,导致下一条指令打断当前语音的混乱情况。
解决方案有两种:
- 粗略延时:在播放后加一个足够长的
暂停,比如暂停(15000)毫秒。简单但笨拙,故事长短不一,时间不好设定。 - 更优方案:利用模块反馈(如果模块支持)。有些语音合成模块在播放结束后会通过串口返回一个特定信号。我们需要在MakeCode中持续监听串口数据,收到结束信号后再切换状态。这需要查阅模块的详细协议文档。对于本项目的Gravity模块,我们可以采用折中方案:估算一个平均故事时长,并在此时间内暂时关闭语音识别,避免干扰。
如果 语音识别到“第一个” 那么 设置变量`当前状态`为 2 语音识别模块禁用 // 关键操作,暂时“关闭耳朵” 语音合成播放 列表“故事内容”[0] 暂停(20000)毫秒 // 根据故事内容估算时间 语音识别模块启用 // 重新“打开耳朵” 设置变量`当前状态`为 0虽然不完美,但在实践中足够稳定可靠。
5. 功能进阶与优化:让机器人更“聪明”
基础的故事点播功能实现后,我们可以为机器人添加更多智能交互功能,提升体验。
5.1 实现智能问答
让机器人不仅能讲故事,还能回答简单问题,比如“乌龟和兔子谁赢了?”。 这需要建立一个问答对列表。
- 列表
问题= [“谁赢了比赛”, “乌鸦用什么喝到水”] - 列表
答案= [“乌龟赢了”, “乌鸦用小石子喝到水”]
当机器人处于“问答模式”(可以设计为状态3)时,它需要将识别到的语音与问题列表中的每一项进行模糊匹配。离线语音识别模块通常返回的是固定指令编号,而不是自由的文本,所以我们需要提前训练。
训练步骤:
- 按住语音识别模块上的“训练键”(通常是KEY1),直到指示灯快闪。
- 清晰地说出问题,例如“谁赢了比赛”。
- 模块指示灯变化,表示训练成功,这个问题被绑定到一个特定的指令编号(比如编号5)。
- 在程序中,当识别到指令编号5时,就播放
答案[0]。
通过这种方式,我们可以建立一个专属的问答知识库。虽然需要预先训练,但准确率极高。
5.2 添加反馈与交互提示
一个好的交互设计应该有明确的反馈。除了语音,我们可以充分利用Micro:bit的LED点阵。
- 聆听中:显示一个闪烁的“耳朵”图标或动态波浪线。
- 识别成功:快速显示一个对勾。
- 识别失败/不理解:显示一个问号,并语音提示“我没听清,请再说一遍”。
- 处理中:显示一个旋转的箭头动画。
这些视觉反馈能极大提升用户体验,让交互过程更直观、更友好。在MakeCode中,我们可以利用显示图标和显示动画积木轻松实现。
5.3 电源管理与项目包装
最后,为了让机器人成为一个独立的“产品”,我们需要考虑供电和外观。
- 供电:断开USB线,使用3节AAA电池盒为Micro:bit供电。确保电池盒能提供足够的电流驱动所有模块。如果语音合成音量小,检查电池是否电量充足。
- 外观:可以用硬纸板、乐高积木或3D打印一个外壳,将Micro:bit和模块固定在里面,露出麦克风和喇叭。设计一个可爱的机器人造型,能立刻吸引孩子的兴趣。
6. 项目总结与扩展思考
回顾整个项目,我们从硬件选型、连接、通信测试,到核心的列表管理与状态机编程,再到功能优化与包装,完成了一个完整的智能硬件作品。这个项目的价值不仅在于做出了一个会讲故事的机器人,更在于它清晰地展示了一个典型的嵌入式交互系统的开发流程:感知(语音识别)-> 处理(Micro:bit程序逻辑)-> 执行(语音合成)。
在这个过程中,有几个关键点值得反复咀嚼:
- 分模块测试:永远不要试图一次性写完所有代码。先让每个模块独立工作,是排除故障、建立信心的最佳方式。
- 状态机思维:对于任何带有交互流程的程序,状态机都是理清逻辑、避免bug的利器。动手画一下状态转换图,会让编程思路清晰十倍。
- 列表的妙用:列表是管理有序数据的瑞士军刀。在这个项目里,它用于管理故事库和问答库。你可以尝试扩展,比如用列表来管理多首儿歌、多个谜语,甚至实现一个简单的播放列表循环功能。
这个项目还有巨大的扩展空间。例如,结合Micro:bit的蓝牙功能,你可以用手机APP来更新故事列表,无需重新烧录程序;或者结合舵机,让机器人在讲故事时摇头晃脑;甚至加入光线传感器,实现“光线暗了,该睡觉了,让我给你讲个晚安故事”的情境化触发。
教育的目的不是复现步骤,而是点燃创意。希望这个“智能伴读机器人”项目,能成为你或你的孩子探索硬件编程与人工智能奇妙世界的一块敲门砖。当你听到自己亲手打造的设备用声音回应你时,那种成就感,是任何现成玩具都无法比拟的。