当前位置: 首页 > news >正文

Grove Vision AI V2之语音控制LED

一、说明

        利用开发板的麦克风、LED、关键字识别模型实现语音控制开发板LED点亮和熄灭,当识别到"on"语音时点亮LED,识别到“off”语音时熄灭LED。

二、程序开发

结合kws_pdm_record和gpio例程开发。

1、创建文件

将kws_pdm_record例程拷贝一份,重命名为kws_led,linux环境下可以执行以下命令:

cp -a kws_pdm_record/ kws_led/

再将部分文件重命名:

2、增加一个APP类型

打开kws_led.mk文件,修改内容:

APPL_DEFINES += -DKWS_PDM_RECORD#-DTFLM_NOTZ
改为
APPL_DEFINES += -DKWS_LED#-DTFLM_NOTZoverride LINKER_SCRIPT_FILE := $(SCENARIO_APP_ROOT)/$(APP_TYPE)/kws_pdm_record.sct
改为
override LINKER_SCRIPT_FILE := $(SCENARIO_APP_ROOT)/$(APP_TYPE)/kws_led.sctoverride LINKER_SCRIPT_FILE := $(SCENARIO_APP_ROOT)/$(APP_TYPE)/kws_pdm_record.ld
改为
override LINKER_SCRIPT_FILE := $(SCENARIO_APP_ROOT)/$(APP_TYPE)/kws_led.ld

打开Seeed_Grove_Vision_AI_Module_V2/EPII_CM55M_APP_S/app/main.c,增加内内容:

#ifdef KWS_LED
#include "kws_led.h"/* main entry */
int main(void)
{board_init();kws_led_app();return 0;
}
#endif
3、编写代码

将kws_led.h改为如下内容:

#ifndef KWS_LED_H
#define KWS_LED_H#define APP_BLOCK_FUNC() do { \__asm volatile("b    ."); \
} while (0)int kws_led_app(void);#endif /* KWS_LED_H_ */

修改kws_led.c文件内容:

#include "kws_pdm_record.h"
改为
#include "kws_led.h"int kws_pdm_record_app(void)
改为
int kws_led_app(void)

三、过程分析

1、音频数据采集
hx_drv_pdm_dma_lli_transfer((void *) audio_buf[w_buf_idx], BLK_NUM, QUARTER_SECOND_MONO_BYTES, 0);

函数用于启动DMA(Direct Memory Access)传输,将音频缓冲区的数据传输到处理单元。 

2、模型加载
cv_kws_init(true, true, KWS_FLASH_ADDR); 

函数初始化关键词唤醒系统,设置为实时模式和唤醒模式,并指定唤醒词模型在闪存中的地址。

3、主循环
cv_kws_run(&algoresult_kws_pdm_record, temp_buf, AUDIO_LEN, kws_processing_callback);

 循环运行关键词唤醒检测函数,传入音频数据和回调函数,用于处理检测结果。

四、识别结果

        kws_led_app()函数中调用cv_kws_run()识别采集的音频数据中是否包含关键字,并传入参数algoresult_kws_pdm_record用于保存识别结果,但是cv_kws_run()函数中未将识别结果赋值给algoresult_kws_pdm_record参数。

        参数algoresult_kws_pdm_record的类型struct_kws_algoResult的定义在Seeed_Grove_Vision_AI_Module_V2/EPII_CM55M_APP_S/library/spi_ptl/spi_protocol.h文件中,定义如下:

#define KWS_MAX_LABEL_SIZE 9typedef struct
{double m_normalisedVal;char m_label[KWS_MAX_LABEL_SIZE];uint32_t m_labelIdx;
}struct_kws_algoResult;

 成员说明:

m_normalisedVal:识别结果置信度;

m_label:存放识别到的标签;

m_labelIdx:标签的序号;

1、保存识别结果

修改cv_kws_run()函数中的内容,增加保存识别结果的代码:

if(vecResults[0].normalisedVal >= threshold)
{xprintf("Label: %s " , vecResults[0].label.c_str());xprintf("Score: %d %", static_cast<int>(vecResults[0].normalisedVal * 100));xprintf("Label Index: %d \n" , vecResults[0].labelIdx);
}
else
{xprintf("None \n");
}

改为

if(vecResults[0].normalisedVal >= threshold)
{algoresult_kws_pdm_record->m_normalisedVal = vecResults[0].normalisedVal;strcpy(algoresult_kws_pdm_record->m_label, vecResults[0].label.c_str());algoresult_kws_pdm_record->m_labelIdx = vecResults[0].labelIdx;xprintf("Label: %s " , vecResults[0].label.c_str());xprintf("Score: %d %", static_cast<int>(vecResults[0].normalisedVal * 100));xprintf("Label Index: %d \n" , vecResults[0].labelIdx);
}
else
{algoresult_kws_pdm_record->m_normalisedVal = 0;xprintf("None \n");
}
2、处理识别结果

修改kws_led_app()函数中的代码,将

if (r_buf_idx > 0) {cv_kws_run(&algoresult_kws_pdm_record, temp_buf, AUDIO_LEN,kws_processing_callback);} else {// Skip processing for the first iterationxprintf("Skipping first buffer processing\n");
}

改为

if (r_buf_idx > 0) {if( cv_kws_run(&algoresult_kws_pdm_record, temp_buf, AUDIO_LEN, kws_processing_callback) == true ){if( algoresult_kws_pdm_record.m_normalisedVal > 0 ){xprintf("kws_led_app Label: %s " , algoresult_kws_pdm_record.m_label);xprintf("kws_led_app Score: %d %", algoresult_kws_pdm_record.m_normalisedVal * 100 );xprintf("kws_led_app Label Index: %d \n" , algoresult_kws_pdm_record.m_labelIdx); if( strcmp( algoresult_kws_pdm_record.m_label, "on") == 0 )  {hx_drv_gpio_set_out_value(GPIO20, GPIO_OUT_HIGH);          //LED ON.}else if( strcmp( algoresult_kws_pdm_record.m_label, "off") == 0 ){hx_drv_gpio_set_out_value(GPIO20, GPIO_OUT_LOW);          //LED OFF.}}           }} else {// Skip processing for the first iterationxprintf("Skipping first buffer processing\n");
}

应用中再次打印识别结果,并加入根据识别到的关键字点亮或关闭LED的代码。

五、LED初始化

在代码pinmux_init();之前加入LED初始化代码:

// The pin of GPIO20 is defined by the user application.
hx_drv_scu_set_SEN_D2_pinmux(SCU_SEN_D2_PINMUX_GPIO20);
// Initialize GPIO_GROUP_2
hx_drv_gpio_init(GPIO_GROUP_2, HX_GPIO_GROUP_2_BASE);
// set GPIO20 as output mode with default output high level
hx_drv_gpio_set_output(GPIO20, GPIO_OUT_HIGH);

六、编译 

1、指定APP_TYPE

将Seeed_Grove_Vision_AI_Module_V2/EPII_CM55M_APP_S/makefile中的APP_TYPE赋值为kws_led:

APP_TYPE = kws_led
2、导入编译工具的环境变量
export PATH="$HOME/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi/bin/:$PATH"
3、编译

cd到EPII_CM55M_APP_S目录,然后执行make clean,再执行make:

cd EPII_CM55M_APP_S
make clean
make

如果之前编译过其它应用,必须执行make clean,不然编译会失败。

未完。。。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • python如何用pymodbus库进行modbus tcp通信解析
  • IO进程线程 240826作业
  • Graylog日志丢失解决方案
  • 人眼检测(单张图像)
  • 工作实战-项目压测记录
  • 如何使用cornerstone3D渲染3D影像
  • WEB应用服务器TOMCAT知识点
  • 8.26算法训练
  • 黑悟空!一区预定!原创首发!SLWCHOA-Transformer-LSTM混合改进策略的黑猩猩优化算法多变量时间序列预测
  • js中Map数据结构使用详细讲解
  • MySQL当表中新增加字段的时候,如何将该字段的值进行快速刷新成对应的值
  • 2024 AI 图像生成器工具合集
  • ssrf漏洞复现分析(1)
  • 网络安全售前入门03——审计类产品了解
  • 出现“此网站无法提供安全的连接,使用了不受支持的协议”的解决方法
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • C++类的相互关联
  • Create React App 使用
  •  D - 粉碎叛乱F - 其他起义
  • Electron入门介绍
  • Fastjson的基本使用方法大全
  • JS 面试题总结
  • python docx文档转html页面
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Quartz初级教程
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 力扣(LeetCode)357
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 排序算法学习笔记
  • 深度学习中的信息论知识详解
  • 关于Android全面屏虚拟导航栏的适配总结
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • 通过调用文摘列表API获取文摘
  • # Redis 入门到精通(一)数据类型(4)
  • # Spring Cloud Alibaba Nacos_配置中心与服务发现(四)
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (2024最新)CentOS 7上在线安装MySQL 5.7|喂饭级教程
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (九十四)函数和二维数组
  • (四)js前端开发中设计模式之工厂方法模式
  • (转载)利用webkit抓取动态网页和链接
  • ... 是什么 ?... 有什么用处?
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .Net Redis的秒杀Dome和异步执行
  • .net 生成二级域名
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .Net6使用WebSocket与前端进行通信
  • .php文件都打不开,打不开php文件怎么办
  • @Autowired 和 @Resource 区别的补充说明与示例
  • @Builder用法