1. 认识安信可VC系列离线语音模组
第一次拿到安信可VC系列模组时,我就被它小巧的尺寸和强大的功能吸引了。这个只有硬币大小的模块,内置了云知声的锋鸟M芯片,能实现完全离线的语音识别。这意味着你不需要联网,不需要服务器支持,直接对着它说话就能控制设备。
VC系列目前主要有VC-01和VC-02两个型号,区别主要在外形尺寸和引脚排布上。核心功能完全一致,都支持:
- 150条本地指令:足够覆盖大多数智能家居场景
- 98%的识别率:实测在2米距离内效果确实不错
- 100ms响应速度:比很多需要联网的方案快得多
- 唤醒词自学习:这个功能很实用,后面会详细介绍
我比较喜欢VC-02的开发板,因为自带USB转串口芯片,调试起来特别方便。板载的三个LED灯(红、绿、蓝)可以直接用来测试GPIO控制功能,省去了外接元件的麻烦。
2. 出厂固件指令解析实战
拿到模组后,我建议先用出厂固件熟悉基本功能。安信可预置了一套完整的智能家居指令集,从唤醒到控制一应俱全。
2.1 指令码格式详解
通过串口调试工具,可以看到每条语音指令都对应一个5字节的指令码。以"打开台灯"为例:
0x5a 0x02 0x00 0x00 0x5c这个结构非常规整:
- 起始位:固定0x5a,相当于帧头
- 指令序号:0x02对应"打开台灯"这条指令
- 两个保留位:目前固定0x00,可能是为未来扩展预留
- 校验位:前四个字节的异或值,用于数据校验
在C语言中验证校验位的代码很简单:
uint8_t verify_checkbit(uint8_t* cmd) { return cmd[0] ^ cmd[1] ^ cmd[2] ^ cmd[3]; }2.2 完整指令表分析
我整理了最常用的20条指令,发现设计很有规律:
| 指令类型 | 指令词示例 | 指令码模式 |
|---|---|---|
| 唤醒相关 | "小安小安" | 0x5a 0x00 ... |
| 灯光控制 | "开灯"/"关灯" | 0x5a 0x02... / 0x5a 0x03... |
| 亮度调节 | "调亮一点" | 0x5a 0x04... |
| 定时功能 | "十分钟后关灯" | 0x5a 0x09... |
特别要注意的是,每条指令支持多个同义词。比如"开灯"这个动作,既可以说"打开台灯",也可以说"请开灯",甚至说"我回来了"都会触发相同的指令码。这个设计在实际产品中很实用,符合自然语言的使用习惯。
3. SDK源码结构初探
当需要自定义功能时,就得深入SDK了。安信可的开源SDK基于RTOS系统,代码结构清晰:
uni_hb_m_solution/ ├── components/ # 核心组件 │ ├── voice_engine # 语音识别核心 │ └── hal # 硬件抽象层 ├── examples/ # 示例代码 ├── user/ # 用户代码区 │ └── src/ │ ├── main.c # 主入口 │ └── examples # 各种功能示例 └── build.sh # 编译脚本3.1 关键代码文件
这几个文件最值得关注:
- user/src/examples/hb_auto_gpio.c:GPIO控制示例
- components/voice_engine/voice_keywords.csv:指令词配置文件
- user/src/main.c:主事件循环
我第一次修改的是回复语,在hb_auto_gpio.c中找到这段代码:
static void _light_on_cb(USER_EVENT_TYPE event, user_event_context_t* context) { event_light_on_t* light_on = NULL; if (context) { light_on = &context->light_on; user_gpio_set_value(GPIO_NUM_A27, 1); // 控制GPIO user_player_reply_list_random(light_on->reply_files); // 随机播放回复语 } }把user_player_reply_list_random的参数改成自定义的语音文件路径,就能修改设备回复语了。
4. 第一个自定义功能开发
现在我们来实战添加一个"切换灯光模式"的新功能。
4.1 修改指令词表
首先在voice_keywords.csv添加新指令:
20,切换模式,0.8字段含义分别是:指令ID、触发词(支持多个用|分隔)、置信度阈值。
4.2 添加事件处理函数
在hb_auto_gpio.c中添加回调函数:
static void _change_mode_cb(USER_EVENT_TYPE event, user_event_context_t* context) { static uint8_t mode = 0; event_change_mode_t* change_mode = NULL; if (context) { change_mode = &context->change_mode; mode = !mode; user_gpio_set_value(GPIO_NUM_A27, mode); // 切换GPIO状态 user_player_play_specific(change_mode->reply_files[0]); // 播放指定回复 } }4.3 注册事件回调
在_register_event_callback函数中添加:
user_event_subscribe_event(USER_CHANGE_MODE, _change_mode_cb);4.4 编译烧录
使用官方提供的编译脚本:
./build.sh update # 生成可串口升级的固件然后用UniOneUpdateTool工具烧录,整个过程大概需要2分钟。
5. 常见问题排查指南
在开发过程中我遇到过几个典型问题:
指令无响应
- 检查麦克风接线是否正确
- 用示波器查看MIC偏置电压(正常应在1.2V左右)
- 确认没有其他噪声源干扰
串口通信异常
- 确认波特率设置为115200
- 检查TX/RX是否接反
- 尝试降低通信速率测试
GPIO控制失效
- 确认在语音平台正确配置了GPIO功能
- 检查是否与其他功能复用引脚
- 测量GPIO实际输出电平
有个特别隐蔽的坑:VC-02的GPIOA25默认被用作唤醒指示灯,如果要用这个引脚控制其他设备,需要先在平台关闭指示灯功能。