市面上的蓝牙语音遥控器方案普遍依赖厂商私有云服务,用户无法自行部署和定制语音处理逻辑。本项目的立项目标是从零打造一款完全开源、可自主部署的 AI 语音遥控器,覆盖从硬件 PCB 设计到云端后台的全链路,让开发者和硬件爱好者可以低成本复现并自由扩展。
核心功能模块包括四个部分:(1)硬件层:基于 ESP32-S3 模组自制 2 层 PCB,集成 PDM MEMS 麦克风、MAX98357A I2S 音频功放、TP4065 锂电池充电管理和 USB Type-C 接口,成品可装入市售遥控器外壳,单台 BOM 成本约 75-95 元;(2)固件层:基于 ESP-IDF v5.4 开发,实现 BLE HID 遥控(键盘/鼠标/多媒体)、SoftAP WiFi 配网(支持多组 WiFi 记忆)、PDM 麦克风采集、I2S 音频播放、HTTPS 语音管线和 OTA 双分区固件升级;(3)Android APP:作为语音桥接端,通过 UDP 接收 ESP32 的音频流,HTTP POST 转发给云端后台处理,再将 TTS 合成的音频回传给遥控器播放,同时提供蓝牙连接管理、WiFi 配网界面和远程日志查看功能;(4)PHP 云端后台:实现可插拔的 ASR→LLM→TTS 语音处理管线,支持 FunASR(免费语音识别)、微软 Edge TTS(免费语音合成)和 DeepSeek 等 OpenAI 兼容大模型 API,并提供 OTA 固件版本管理后台和 API 日志监控面板。
业务流程为:用户按下遥控器语音键 → ESP32 PDM 麦克风采集 16kHz PCM 音频 → 优先通过 UDP 发送给 Android APP 桥接转发(本地模式),若 APP 不可达则自动切换为 HTTPS 直连云端(云端模式)→ Web 后台依次执行语音识别(FunASR,约 1 秒)、大模型生成回复(DeepSeek,约 1.5 秒)、语音合成(Edge TTS,约 0.7 秒)→ PCM 音频通过 HTTP 响应返回 → ESP32 I2S 播放语音回复。整个流程端到端延迟约 3-4 秒。遥控器同时支持 BLE HID 标准协议,可直接控制 PC、电视、智能家居设备的方向键、确认键和多媒体按键。
本项目由我独立完成全部的硬件设计、固件开发、Android APP 开发和 Web 后台开发。
GitHub开源项目名称为esp32s3-ble-voice-remote。
整体架构采用"端—边—云"三层设计:端侧为 ESP32-S3 遥控器负责音频采集和 BLE HID 遥控,边侧为 Android APP 提供 UDP 音频桥接和用户交互界面,云侧为 PHP+MySQL 后台执行 ASR/LLM/TTS 语音处理。两种工作模式(本地 UDP 桥接 和 云端 HTTPS 直连)可自动切换,保证在有无手机 APP 的场景下遥控器都能正常使用。
各模块技术栈:硬件使用立创 EDA 绘制原理图和 PCB Layout,嘉立创制板,手工贴片焊接 0402 封装元件;固件使用 C 语言基于 ESP-IDF v5.4 框架开发,涉及 FreeRTOS 多任务调度、BLE GATT/HID Profile、WiFi STA/SoftAP 双模、mbedTLS HTTPS 客户端、esp_http_client 和 esp_https_ota 组件;Android APP 使用 Java 基于 Android Studio 开发,涉及 BLE API、UDP Socket、HTTP 多线程通信;Web 后台使用 PHP 8.x + MySQL,Python Flask 微服务承载 FunASR 和 Edge TTS 引擎,Apache 部署。
我在项目中遇到的主要难点和解决方案其二:(1)ESP32 内部 RAM 不足导致 TLS 握手失败——由于 BLE、WiFi、HTTP 服务器、HTTPS 客户端和日志服务同时运行,internal RAM 一度降至 14KB,mbedTLS 分配失败报 esp-aes Failed to allocate memory。解决方案是启用 mbedTLS 动态缓冲区(MBEDTLS_DYNAMIC_BUFFER),将日志系统的环形缓冲区迁移到 PSRAM,使用 FreeRTOS 队列将 vprintf hook 中的耗内存操作卸载到独立任务,最终 internal RAM 恢复到 49KB 以上。(2)语音数据跨线程同步——Android APP 中 BLE 音频回调和 UDP 音频接收分别运行在不同线程,语音会话的起止检测和 PCM 数据累积需要线程安全地协同工作。解决方案是引入 synchronized 锁和共享 ByteArrayOutputStream 缓冲区,统一由 onVoiceSessionStart/End 管理语音会话生命周期,确保两种音频来源都能正确触发 Web 后台的语音处理