安信可VC-01/02二次开发篇: 事件和GPIO控制

描述

安信可离线语音VC01/02:硬件规格书、开发资料、烧录工具、应用开发

安信可离线语音模组 VC-01、VC-02 系列教程 【基础认知篇】

安信可离线语音模组 VC-01、VC-02 系列教程 【快速上手篇】

安信可离线语音模组 VC-01、VC-02 系列教程 【中级入门篇】

安信可离线语音模组 VC-01、VC-02 系列教程 【高级进阶篇】

安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】虚拟开发环境搭建和分享

安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】事件和GPIO控制

安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】PWM输出

安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】串口输出

安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】SDK音频替换失败记录过程

安信可离线语音模组 VC-01、VC-02 系列教程 【二次开发篇】自定义音频播放控制

简介

在上一篇文章中,我们已经成功搭建好了VC系列的Linux开发环境,使用VScode进行了远程连接,成功进入到了下载后的SDK固件源码中,并且进行了编译等操作。

在本章我将对SDK中常见的模块进行解析,并且带着大家编译一个通过安信可语音平台生成固件中的语音唤醒或者控制事件在源码中进行自定义的操作(即在安信可语音平台生成语音唤醒词和控制命令的时候,并不指定控制行为而是通过在SDK里指定控制行为)。

准备工作

首先给大家看一下默认生成的固件配置信息(来自安信可语音平台

GPIO

下图为配置的控制行为。

GPIO

可以从以上两个图中看到, 我们仅仅是配置了默认的唤醒和1个控制行为。 但是这个控制行为并没有对应的命令(无法点亮LED灯或者关闭LED灯)。

之后我们生成对应的SDK,并把它下载到虚拟机中(替换上一个帖子中下载的SDK,在文末会附上本次生成的SDK文件)。

GPIO

SDK重要组件介绍

1、首先看

~/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/tools/scripts下的tones 目录和 wav_tones 目录。

GPIO

这两个目录主要保存安信可语音平台生成的音频文件。

即所有的音频输出(唤醒词回复词等),在程序编译后,其音频文件会被编译成PCM文件,然后由VC-01/ 02进行播放。

2、开发板PIN初始化配置信息

/home/vc02/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/tools/scripts/custom_config.json

GPIO

当前的文件主要记录了在安信可语音平台中配置的PIN的初始化信息。

如下图所示(不建议在代码中配置, 推荐使用安信可语音平台进行)。

GPIO

3、cmd_reply_data.json 文件,

位于/home/vc02/Downloads/uni_hb_m_solution/unione_lite

_app_hb_m/tools/scripts/ 下

GPIO

拿唤醒词“你好小美”举例子, 这里主要的JSON key 有PCM, CMD

PCM决定当前的命令词触发的时候将会播放哪些音乐

CMD则是做为对应唤醒事件的KEY(稍后会解释这个是什么意思)

4、二次开发集成的example配置文件user_config.h 文件,

位于 ~/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/user/inc

GPIO

在默认的SDK中,其开启的Macro 为 USER_DEMO_AUTO_GPIO 。 所以用户的自定义功能将会使用example下的hb_auto_gpio.c 文件作为额外自定义功能。

以此类推,如果开启的是USER_DEMO_BUZZER 宏, 那么开启的Demo则为

/home/vc02/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/user/src/examples

下的hb_timer_buzzer.c

GPIO

而当前开发板所有支持的二次开发的库函数的定义则都

/home/vc02/Downloads/uni_hb_m_solution/unione_lite_app_hb_m/user/inc 目录下。

GPIO

这里所有库函数对应的例程都可以从example下找到。

5、user_event.h 位于inc 目录下, 此文件记录了所有开发板中可以触发的事件。 比如说识别到“”你好小美“或者是识别到对应的命令。

GPIO

typedef enum {

USER_INVALID_EVENT = 0, ///< 错误的事件类型

USER_AUDIO_PLAY_START, ///< 音频开始播放时发送

USER_AUDIO_PLAY_END, ///< 音频播放完毕或被停止时发送

USER_CUSTOM_SETTING, ///< 识别到客户自定义的识别词时发送

USER_VOLUME_SETTING, ///< 识别到音量调节指令时发送

USER_GOTO_SLEEPING, ///< 进入待唤醒状态时发送

USER_GOTO_AWAKENED, ///< 进入识别状态(已唤醒)时发送

USER_EVENT_MAX

}USER_EVENT_TYPE;

上述列举了所有可以被用户订阅的事件,当对应的事件触发的时候,也会触发事件的callback function。

/** @brief 事件内容,共用体,根据事件类型具体处理*/

typedef union {

event_audio_play_t audio_play; ///< 对应USER_AUDIO_PLAY_START事件

event_audio_end_t audio_end; ///< 对应USER_AUDIO_PLAY_END事件

event_custom_setting_t custom_setting; ///< 对应USER_CUSTOM_SETTING事件

event_volume_setting_t voluem_setting; ///< 对应USER_VOLUME_SETTING事件

event_goto_sleeping_t goto_sleeping; ///< 对应USER_GOTO_SLEEPING事件

event_goto_awakend_t goto_awakend; ///< 对应USER_GOTO_AWAKENED事件

}user_event_context_t;

针对于上述事件的每一个事件, 其具备对应的事件内容。 比如说用户订阅了USER_GOTO_AWAKENED 事件。

那么便可以从user_event_context_tgoto_awakend 捕获到对应的事件内容,而对应事件的内容信息则被下述结构体定义,只举例唤醒事件(其他事件同理)。

typedef struct {

EVENT_TRIGGER trigger; ///< 触发来源

char *cmd; ///< 命令词意图,对应UDP平台上用户定义脚本中的action

char *word_str; ///< 识别到的命令词

char *reply_files; ///< 回复语列表[1, 2, 3],对应UDP平台上用户定义脚本中的回复语列表,在pcm_map.txt中可以找到对应关系

}event_goto_awakend_t;

这样就可以通过CMD来获取到对应的命令!

这里可以解释在 3- cmd_reply_data.json 文件中所说明的JSON KEY对应Value的作用。即用户可以根据对应的事件,判断对应的CMD来自定义行为,其支持的行为为所有Inc文件夹下包含的库函数。

GPIO控制

(通过使用唤醒词“你好小美”并关闭LED,使用命令词“打开台灯”打开LED)

明白原理之后, 我们便可以开始着手来开发GPIO功能, 即通过使用唤醒词:你好小美。关闭LED,使用命令词:打开台灯。打开LED。

需要注意的是: "你好小美" 是属于唤醒事件, 而打开台灯是属于命令事件。 打开台灯必须在你好小美之后触发。明白原理之后就可以很轻松的在example下的hb_auto_gpio.c 进行修改 (默认启用,上文有介绍)

首先在原本的_register_event_callback 方法中额外注册一个用户唤醒事件的回调:

user_event_subscribe_event(USER_GOTO_AWAKENED, _custom_setting_cb2);

如下图所示

GPIO

之后拷贝原本的 _custom_setting_cb 方法

改名为 _custom_setting_cb2 (我这里不规范, 不要学习我这样的随意命名, 可以改成_custom_setting_wakeup_cb)。

static void _custom_setting_cb2(USER_EVENT_TYPE event,

代码解析:由于订阅的是USER_GOTO_AWAKENED 事件, 所以其联合体中goto_awakend 才会具有数据,因此需要根据上下文中的context 来获取到对应的goto_awakend从而来获取到对应的CMD命令 "wakeup_uni" (被cmd_reply_data.json 定义, 上文有介绍)。

这样就可以实现, 当识别到“你好小美” 的时候关闭LED灯。

同理可以实现通过命令词打开LED灯,代码如下所示:

static void _custom_setting_cb(USER_EVENT_TYPE event,

最终当识别到 “你好小美”的时候便会关闭LED, 当识别到 “打开台灯”等命令词的时候便会打开LED,实现用户的自定义控制~

编译烧录和测试

接下来可以在SDK的根目录来编译自己的固件了,执行命令:

./build.sh update

GPIO

此时可以打开output 文件夹,然后把uni_app_release_update.bin下载到本地电脑,使用 UniOneUpdateTool.exe 进行烧录。

GPIO

下图为烧录成功界面:

GPIO

实验

使用 “你好小美” 唤醒VC-02, 通过命令词“打开台灯”, LED 灯被点亮。

GPIO

使用 “你好小美” 唤醒VC-02, LED灯被熄灭。

GPIO

附件

固件和SDK

https://www.123865.com/s/UNArVv-k4UKd

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分