ESP32-C6+旧手机:语音控制小车实战

2026-10-22 10:03:58 2阅读

不用买屏幕、不用摄像头、不用云主机,用一部闲置的旧手机当交互终端,一块DFRobot FireBeetle 2 ESP32-C6做主控,再接入硅基流动大模型API(语音识别+大模型对话+语音合成),就能做出一台会说、会听、会按指令移动的语音控制小车。你只需对它说"先前进,再左转,再右转",小车就会依次完成三个动作;问它"今天天气怎么样",它会用稳定的音色回答你。整个网页就托管在C6的Flash里,手机打开浏览器即可使用,完全不需要电脑中转、不需要第三方物联网平台。

项目架构

旧手机(浏览器) --WiFi(2.4G)--> FireBeetle 2 ESP32-C6(HTTPS网页服务器)
 |  |
 | 按住说话/自动听 | L298N 双H桥
 v  v
 录音 -> 硅基流动 Qwen3-ASR --> 文字 --> 硅基流动 Qwen3-8B/32B 对话
  |
 播放 MOSS-TTSD 合成语音 <---------- 输出 actions:[FORWARD,LEFT,...]
  |
  +--------------+
  v
 C6 按顺序执行动作(前进2秒/转向1秒,自动停车)

为什么手机要配C6,而不直接用手机控制电机?

浏览器受安全限制,不能直接驱动GPIO、不能发原始UDP,录音/摄像头还必须HTTPS。C6做"大脑+关节":提供HTTPS网页、解析指令、驱动电机,手机只负责"声音交互"。

材料清单

类别名称数量说明
主控DFRobot FireBeetle 2 ESP32-C6 (DFR1075)1板载LED(IO15)、支持Wi-Fi 6
驱动L298N双H桥电机驱动板1两路电机,PWM调速
电机直流减速电机(带轮小车底盘)2左右轮各一
电源3.7V锂电池1进L298N 12V端子;C6用Type-C或电池供电
交互闲置旧手机(安卓/iOS均可)1与C6同连一路由器(2.4G)
调试Type-C数据线1烧录+串口监视
服务硅基流动(SiliconFlow) API--注册获得API Key,使用赠送额度即可

接线(L298N 与 C6)

务必共地:L298N的GND与C6的GND相连,否则信号不识别。

C6引脚(GPIO)方向L298N端子作用
GPIO2 (M1_IN1)-->IN1(A通道)左轮方向1
GPIO3 (M1_IN2)-->IN2(A通道)左轮方向2
GPIO4 (M1_PWM)-->ENA左轮速度PWM
GPIO5 (M2_IN1)-->IN3(B通道)右轮方向1
GPIO6 (M2_IN2)-->IN4(B通道)右轮方向2
GPIO7 (M2_PWM)-->ENB右轮速度PWM
GND<-->GND共地(必须)
电池3.7V-->12V/VCC电机电源

引脚定义在主程序顶部,可按实际焊接修改;若转向相反,互换该轮两根IN线即可。

软件与模型

开发环境

Arduino IDE(2.x均可),安装Espressif ESP32板卡包(3.x)。开发板选择:DFRobot FireBeetle 2 ESP32-C6。工具中设置USB CDC On Boot = Enabled(否则串口在程序运行后会断开)。

硅基流动模型

用途模型ID说明
语音识别ASRQwen/Qwen3-ASR-1.7B支持52种语言/方言,识别准、返回快
对话/动作决策Qwen/Qwen3-8B(默认)快;可换32B更强
语音合成TTSfnlp/MOSS-TTSD-v0.5音色fnlp/MOSS-TTSD-v0.5:alex,稳定

浏览器直连可行(CORS已放行),无需任何中转服务器。

程序结构

firebeetle2_voice_robot/
+-- firebeetle2_voice_robot.ino (C6主程序,HTTPS服务器+动作控制)
+-- page.h (网页HTML+JS全内嵌,放头文件防注入)
+-- certificates.h (自签名证书,DER二进制)

C6侧核心逻辑

void processCommand(String cmd) {
  cmd.trim(); cmd.toUpperCase();
  Serial.print("[CMD] "); Serial.println(cmd);
  if (cmd == "FORWARD") { startMotion("FORWARD", 2000); }
  else if (cmd == "LEFT" || cmd == "RIGHT") { startMotion(cmd, 1000); }
  else { stopMotionNow(); }
}

两个网页服务:HTTP :80与HTTPS :443(mbedtls自签名)。动作执行后自动停车,等待新指令。

网页功能

功能说明
按住说话按住录音、松开识别(指针捕获,长按不选中文字)
持续听(人声唤醒)听到人声自动录音->识别->对话;1.5秒PCM预卷不漏开头;播报自己声音自动忽略
AI对话Qwen3-8B/32B,思考模式关闭,回复简短;可一次输出多个动作连续执行
语音播报MOSS-TTSD固定音色,失败自动重试保持音色;结尾杂音自动裁剪
左右轮调速两个滑块独立调PWM(默认左240/右255)

制作步骤

1. 烧录:用Arduino IDE打开主程序,选板卡"DFRobot FireBeetle 2 ESP32-C6",CDC On Boot=Enabled,上传。

2. 配置WiFi:改主程序顶部WIFI_SSID/WIFI_PASS(C6仅支持2.4GHz);默认静态IP可按路由器网段修改。

3. 配API Key:page.h顶部API_KEY换成你的硅基流动Key。

4. 串口监视器(115200)看到:WiFi已连接、HTTPS已启动,板载LED闪两下。

5. 手机:连同一WiFi,打开https://C6的IP(自签名证书 -> 高级 -> 继续访问)。

6. 先点"试听播报"验证链路,再按住说话或开启持续听。

技术难点与解决

1. 浏览器不能裸发UDP/录音必须HTTPS

C6用mbedtls做自签名HTTPS服务器,证书以DER二进制内嵌,手机浏览器"高级->继续访问"即可。

2. Arduino的"生成函数原型"会把#line注进HTML,毁掉页面JS

把网页HTML移进page.h头文件(原型生成器只处理.ino,不碰头文件)。这是"同一份代码有时页面白屏"类问题的根源。

3. 老手机浏览器不支持现代JS

页面JS用ES5兼容写法+拆成两个script块:第一块做极简启动自检,一眼判断是"浏览器不支持"还是"页面问题"。

4. 持续听漏掉开头几个字

用PCM预卷环(始终保留最近1.5秒音频),检测到人声即把预卷拼回录音,开头一字不丢。

5. TTS音色忽男忽女/结尾有杂音

固定音色,接口失败自动重试保持音色;播放前解码并按结尾静音裁剪,同时先停掉上次播放防重叠串音。

6. 一次说多个动作

对话里约定输出JSON格式包含reply和actions数组,网页解析后逐个发送并等上一个动作完成再下一个。

注意事项

API Key内嵌在网页里,仅限自家局域网使用,勿上传公开仓库;被其他人连到同一WiFi即可使用你的Key,注意额度。C6只支持2.4GHz WiFi;手机最好连2.4G段信号更稳。L298N必须与C6共地;电机单独由电池供电,不要从C6引脚取电。


作者:云天
链接:https://www.aiddithome.com/p/5540ab4ba2eb7.html
本作遵循 [CC BY 4.0 署名] 许可,版权归作者所有。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
5条评论
周五下班搞一搞
1楼 · 1小时前

ES5兼容写法照顾老手机浏览器,考虑周全

入门没多久的新手
2楼 · 1小时前

自签名HTTPS服务器这个方案实用,省了第三方平台

隔壁工位的好奇宝
3楼 · 1小时前

PCM预卷环防漏字的技巧学到了,之前做语音项目一直头疼这个问题

阿伟不emo
4楼 · 1小时前

L298N和C6共地这个细节很重要,很多人会忘

第三次终于亮了
5楼 · 1小时前

旧手机再就业这个思路太赞了,ESP32-C6做主控成本也不高