2026寒假练 基于RP2040游戏机+麦克风模块实现声控小游戏
该项目使用了RP2040游戏机+麦克风模块,实现了声控小游戏的设计,它的主要功能为:基于RP2040游戏机+麦克风模块实现声控小游戏。
标签
游戏机
麦克风
寒假练习
冲向天空的猪
更新2026-03-24
39

基于RP2040的语音控制跳跃游戏项目总结报告

一、所选任务介绍

本项目选定的任务是实现一个基于语音识别的游戏控制系统,具体要求是使用能量、时长与间隔规则识别两个简单口令("开始"和"返回"),并能够在菜单与游戏内都用语音触发,同时在屏幕上提示识别结果。

在实际实现中,我选择了两个更具游戏性的口令:"JUMP"(跳跃)"RESTART"(重开)。这两个口令通过语音时长的差异进行区分,能够完整地控制一个类似谷歌浏览器恐龙游戏的跳跃游戏。该任务的核心挑战在于在资源有限的嵌入式系统(RP2040)上实现高效的语音识别,并将其无缝集成到游戏系统中,提供流畅的用户体验。

二、项目介绍

本项目是基于树莓派RP2040微控制器开发的语音控制跳跃游戏系统。系统通过麦克风采集用户语音信号,利用语音时长的特征差异来识别不同的控制指令,驱动LCD显示屏上的游戏角色进行跳跃或重新开始游戏。

项目采用极简的语音识别算法,不依赖复杂的神经网络或庞大的语音模型,而是巧妙地利用了人类发音时长的自然差异。通过学习阶段,系统记录用户说出"跳"和"R重开T"两个口令的时长特征,然后根据时长的相对长短建立识别阈值,在游戏运行时实时识别用户指令。

游戏本身是一个经典的自动奔跑跳跃游戏:一个蓝色的恐龙角色在地面上奔跑,仙人掌障碍物不断从右侧出现,玩家需要在适当的时候发出"JUMP"指令让恐龙跳跃避开障碍物。当恐龙碰撞到障碍物时游戏结束,此时可以发出"RESTART"指令重新开始游戏。整个游戏过程完全通过语音控制,无需按键操作,提供了独特的交互体验。

系统还集成了实时显示功能,在屏幕左上角显示最近识别到的指令,在右上角显示当前得分,让用户能够直观地了解语音识别的效果和游戏进度。

三、硬件介绍

本项目使用的硬件组件主要包括:

1. RP2040微控制器开发板

RP2040是树莓派基金会推出的一款低成本、高性能的双核ARM Cortex-M0+微控制器。它具有以下特点:

  • 双核处理器,运行频率高达133MHz
  • 264KB SRAM和2MB板载Flash存储
  • 丰富的外设接口,包括SPI、I2C、UART、ADC、PWM等
  • 支持MicroPython编程,适合快速原型开发
  • 低功耗设计,适合电池供电的便携应用

3. 麦克风模块

  • 类型:模拟输出麦克风
  • 连接方式:通过ADC接口连接
  • 功能:采集用户的语音信号,将声波转换为模拟电压信号供RP2040采样

四、方案框图和项目设计思路介绍

4.1 系统总体框图

┌─────────────┐
│   用户语音   │
└──────┬──────┘
      │ 声波
      ↓
┌─────────────┐
│ 麦克风模块 │
└──────┬──────┘
      │ 模拟信号
      ↓
┌─────────────┐
ADC采样   (RP2040)
└──────┬──────┘
      │ 数字信号
      ↓
┌─────────────────────────┐
│   语音处理与识别模块     │
- 能量检测             │
- 时长计算             │
- 阈值判定             │
└──────┬──────────────────┘
      │ 识别结果
      ↓
┌─────────────────────────┐
│     游戏控制模块       │
- 状态管理             │
- 碰撞检测             │
- 得分统计             │
└──────┬──────────────────┘
      │ 图形数据
      ↓
┌─────────────┐
ST7789显示屏│
└─────────────┘

4.2 项目设计思路

本项目的核心设计思路是"简单但有效",具体体现在以下几个方面:

4.2.1 语音识别策略

没有采用复杂的频域分析或机器学习算法,而是利用了语音的时域特征——时长。这种方法的优势是:

  • 计算量小,适合资源受限的嵌入式系统
  • 实现简单,代码易于理解和调试
  • 响应快速,满足游戏的实时性要求
  • 通过学习阶段适应不同用户的发音特点

4.2.2 异步任务架构

采用MicroPython的uasyncio异步编程框架,将系统分解为多个独立的协程任务:

  • 语音采集任务mic_task):持续监听麦克风输入,计算语音时长,更新识别结果
  • 游戏引擎任务engine_task):处理游戏逻辑、碰撞检测、图形绘制
  • 显示更新任务:实时显示识别结果和游戏状态

这种设计确保了语音识别和游戏运行互不阻塞,保证了系统的流畅性。

4.2.3 状态机设计

系统采用清晰的状态机管理游戏流程:

  • LEARN(学习状态):引导用户录制两个口令,建立识别阈值
  • PLAY(游戏状态):正常运行游戏,响应语音指令
  • GAME OVER(结束状态):显示游戏结束画面,等待重新开始指令

4.2.4 用户反馈机制

  • 屏幕左上角实时显示最近识别到的指令(如"JU"、"RE"、"--")
  • 右上角显示当前得分
  • 学习阶段显示录制进度和测得的时长数据
  • 游戏结束时有明确的提示信息

五、调试软件及使用的编程语言说明、软件流程图及关键代码介绍

5.1 编程语言与开发环境

  • 编程语言:MicroPython
  • 开发环境:Thonny

5.2 软件流程图

        ┌──────────────┐
      │   系统启动   │
      └──────┬───────┘
              ↓
      ┌──────────────┐
      │ 初始化硬件   │
      (ADC/SPI/LCD)
      └──────┬───────┘
              ↓
      ┌──────────────┐     是
      │ 进入学习模式 │◄─────────┐
      └──────┬───────┘         │
              ↓                 │
      ┌──────────────┐         │
      │ 提示录制JUMP │         │
      └──────┬───────┘         │
              ↓                 │
      ┌──────────────┐         │
      │ 采集语音时长 │         │
      └──────┬───────┘         │
              ↓                 │
      ┌──────────────┐         │
      │ 提示录制RESTART│         │
      └──────┬───────┘         │
              ↓                 │
      ┌──────────────┐         │
      │ 采集语音时长 │         │
      └──────┬───────┘         │
              ↓                 │
      ┌──────────────┐         │
      │ 计算识别阈值 │         │
      └──────┬───────┘         │
              ↓                 │
      ┌──────────────┐         │
      │ 进入游戏模式 │─────────┘
      └──────┬───────┘
              ↓
    ┌────────────────┐
    │   主循环开始   │
    └───────┬────────┘
            ↓
    ┌────────────────┐
    │ 语音采集任务   │ ──────┐
    │ - 检测声音     │       │
    │ - 计算时长     │       │
    │ - 更新指令     │       │
    └────────────────┘       │
            ↓               │
    ┌────────────────┐       │
    │ 游戏引擎任务   │       │
    │ - 处理指令     │       │
    │ - 移动角色     │       │
    │ - 碰撞检测     │       │
    │ - 绘制图形     │◄──────┘
    └───────┬────────┘
            ↓
    ┌────────────────┐
    │ 游戏结束?   │────否──┐
    └───────┬────────┘       │
          是               │
            ↓               │
    ┌────────────────┐       │
    │ 等待RESTART指令│───────┘
    └────────────────┘

5.3 关键代码介绍

5.3.1 语音采集函数(核心算法)

async def capture_voice_profile(is_game=False):
   # 等待声音触发
   while True:
       val = abs(adc.read_u16() - ADC_BIAS)
       if val > MIC_THRESHOLD: break
       await asyncio.sleep_ms(1)
   
   if is_game: env.instant_jump = True
   
   start_t = utime.ticks_ms()
   last_act = start_t
   
   # 持续采样直到完全安静
   while True:
       now = utime.ticks_ms()
       val = abs(adc.read_u16() - ADC_BIAS)
       
       # 只要还有声音,就更新最后活跃时间
       if val > (MIC_THRESHOLD * 0.6):
           last_act = now
           
       # 静默超过 200ms 则认为说话结束
       if utime.ticks_diff(now, last_act) > SILENCE_GAP: break
       # 强制保护:发音不能超过 1.2
       if utime.ticks_diff(now, start_t) > 1200: break
       await asyncio.sleep_ms(1)
   
   # 计算声音的总时长
   dur = utime.ticks_diff(last_act, start_t)
   return dur

设计要点

  1. 触发检测:持续监测ADC值,当声音能量超过阈值(MIC_THRESHOLD=1800)时开始记录
  2. 静默检测:记录最后有声时刻(last_act),当静默持续超过200ms(SILENCE_GAP)时判定说话结束
  3. 超时保护:强制限制最大时长为1.2秒,防止误触发或系统卡死
  4. 游戏模式优化:在游戏过程中检测到声音时立即设置跳跃标志(instant_jump),提高响应速度

5.3.2 学习模式实现

if env.state == "LEARN":
   for key in ["JUMP", "RESTART"]:
       display.fill(st7789.BLACK)
       display.text(font, "SAY: " + key, 20, 80, st7789.CYAN)
       display.text(font, "Wait...", 20, 130, st7789.WHITE)
       dur = await capture_voice_profile(False)
       env.features[key] = dur
       display.text(font, "Dur: %dms"%dur, 20, 170, st7789.YELLOW)
       await asyncio.sleep(1)
   
   # 计算分界线:(短音时长 + 长音时长) / 2
   env.jump_limit = (env.features["JUMP"] + env.features["RESTART"]) / 2
   reset(); env.state = "PLAY"

设计要点

  • 依次引导用户录制两个口令
  • 显示测得的时长数值,方便用户了解自己的发音特点
  • 自动计算识别阈值(两个时长的平均值),无需用户手动调整

5.3.3 语音识别与判定

async def mic_task():
   while True:
       if env.state == "PLAY":
           dur = await capture_voice_profile(is_game=True)
           if dur > 0:
               # 只有比分界线长,才判定为 RESTART
               if dur > env.jump_limit:
                   env.cmd = "RESTART"
               else:
                   env.cmd = "JUMP"
               
               await asyncio.sleep_ms(400) # 显示暂留
               env.cmd = "--"
           await asyncio.sleep_ms(10)
       await asyncio.sleep_ms(5)

设计要点

  • 简单的阈值判定:时长小于阈值为"JUMP",大于阈值为"RESTART"
  • 显示保持:识别结果在屏幕上显示400ms,方便用户确认
  • 防重复触发:识别完成后重置指令为"--"

5.3.4 游戏物理引擎

draw_dino(P_X, int(py), st7789.CYAN, env.frame if not is_jumping else 0)

py += vy
if py < G_Y-P_SIZE: vy += 2.8
else: py, vy, is_jumping = G_Y-P_SIZE, 0, False

if env.instant_jump:
   if not is_jumping: vy = -18; is_jumping = True
   env.instant_jump = False

设计要点

  • 简单的物理模拟:重力加速度为2.8像素/帧²
  • 瞬时跳跃:检测到声音立即给予-18的向上速度
  • 地面碰撞检测:当角色到达地面时停止下落

5.3.5 障碍物生成与碰撞检测

gap_min = 100 + (env.base_speed * 2)
if random.random() < 0.04 and (not obstacles or obstacles[-1] < (240 - gap_min)):
   obstacles.append(238)

for ox in obstacles:
   draw_cactus(ox, G_Y-30, clear=True)
   nx = ox - env.base_speed
   if (P_X < nx + 15) and (P_X + 22 > nx) and (py + 25 > G_Y - 30):
       env.running = False

设计要点

  • 动态难度:障碍物最小间距随游戏速度增加
  • 碰撞检测:使用矩形相交算法
  • 随机生成:4%的概率生成新障碍物

六、功能展示图及说明

6.1 学习模式界面

在系统启动后,首先进入学习模式。屏幕上会依次显示:

  • "SAY: JUMP" - 提示用户说"跳跃"
  • "Wait..." - 等待声音输入
  • "Dur: XXXms" - 显示录制的时长(例如"Dur: 350ms")

然后继续录制"RESTART"指令,完成后自动进入游戏模式。

c863702038575be2a11b79ec11470552.jpg

6.2 游戏运行界面

游戏正常运行时,屏幕显示内容包括:

  1. 游戏画面
    • 左侧:蓝色的恐龙角色(由矩形组成)
    • 右侧:从右向左移动的绿色仙人掌障碍物
    • 底部:白色地面线条

1c3551c22b00afa11cd6acc581a7c4a7.jpg

  1. UI信息
    • 左上角:识别指令提示
      • "JU" - 识别到跳跃指令
      • "RE" - 识别到重新开始指令
      • "--" - 等待输入
    • 右上角:当前得分(例如"015"表示得分15)
  2. 动画效果
    • 恐龙奔跑时腿部交替摆动
    • 跳跃时腿部静止
    • 仙人掌平滑移动

6.3 游戏结束界面

当恐龙碰撞到障碍物时:

  • 游戏角色停止移动
  • 屏幕中央显示"GAME OVER"(红色文字)
  • 下方显示"SAY RESTART"(白色文字)
  • 此时说出"RESTART"口令即可重新开始游戏

ec08e3c926e31e9734e5fbd79b04ecea.jpg

6.4 实物展示说明

image.png

七、项目中遇到的难题及解决方法

7.1 语音识别的误触发问题

问题描述
在初期实现时,系统经常受到环境噪音的误触发,导致游戏角色意外跳跃,严重影响游戏体验。

解决方法

  1. 调整能量阈值:将MIC_THRESHOLD从2000降低到1800,平衡灵敏度和抗干扰能力
  2. 增加静默检测:引入SILENCE_GAP参数(200ms),只有当声音持续一段时间后才开始计时
  3. 超时保护:限制最大录制时长为1.2秒,防止长时间噪音占用系统资源
  4. 动态阈值:在静默检测中使用60%的阈值(MIC_THRESHOLD * 0.6),更准确地判断说话结束

7.4 跳跃响应延迟问题

问题描述
从用户说出指令到角色开始跳跃存在明显延迟,影响了游戏的操作手感。

解决方法

  1. 即时跳跃标志:在语音检测到声音时立即设置instant_jump标志,而不是等待完整的语音采集结束
  2. 优先处理:在游戏循环中优先检查instant_jump标志,确保响应最快
  3. 降低ADC采样延迟:将语音采集任务从阻塞式改为异步式,减少对主循环的影响
  4. 优化阈值判定:简化语音时长计算逻辑,减少计算时间


附件下载
code.py
团队介绍
个人
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号