更新时间:2025-08-29 07:19:36下载pdf
通过 ASR PRO 语音识别模组,最多能够实现 5 个自定义唤醒词,其在功能上具有以下两点优势:
硬件 | 功能参数 |
---|---|
T5 开发板 | AI 对话核心板 |
ASR PRO 模组 | 支持自定义唤醒词和离线语音识别 |
串口板或 ASR-LINK 自动下载器 | 普通的 CH340 串口板即可,用于给 ASR PRO 下载程序 如果有条件可以自行购买 ASR-LINK 自动下载器 |
咪头 | 用于给 ASR RPO 模组拾音 |
芯片规格书:点击查看
外观图:
首先需要对 ASR PRO 进行编程和固件烧录,然后将 ASR PRO 模组连接到 T5 开发板,因此接线分成两部分:
ASR PRO 模组 | 串口板 |
---|---|
GND | GND |
5V | 5V |
PB5(UART0 TX) | RX |
PB6(UART0 RX) | TX |
MIC + | 咪头 + |
MIC - | 咪头 - |
T5 开发板 | ASR PRO 模组 |
---|---|
GND | GND |
5V | 5V |
P10(UART0 TX) | PB5(RX) |
P11(UART0 RX) | PB6(TX) |
P12(唤醒脚) | PA4(演示使用,可自定义) 注意:如果使用串口程序唤醒,可以不接 P12 唤醒引脚 |
Tuya AI 智能体支持多角色,ASR PRO 模组支持最多 5 个唤醒词,每个唤醒词有单独的识别标识 ID,因此可以考虑设计一个程序为每个角色设计一个专有唤醒词。在制作 ASR PRO 程序时可以用识别标识 ID 来区分唤醒词,比如识别到不同的标识 ID 控制不同的 IO 引脚拉低,或者也可以通过串口将数据发送到需要连接的主控芯片 T5 上。
通常使用 天问 Block 开发 ASR PRO 模组,其图形化编程对新手非常友好。您可以点击前往 天问 51 官网 下载。
系统配置三个唤醒词,分别为 “你好哪吒”、“你好猪八戒”、“你好柯南”。当 ASR PRO 模组识别到上述任一唤醒词时,需通过 IO 接口触发唤醒功能,同时通过串口输出数据:
唤醒词 | 串口输出 |
---|---|
你好哪吒 | A0 01 00 |
你好猪八戒 | A0 01 01 |
你好柯南 | A0 01 02 |
关于固件烧录的方法,请参考 视频教程。
参考图:
IO 唤醒相对易操作,只需要将 ASR PRO 设置的唤醒脚连接到 T5 唤醒脚(默认 P12)即可。
串口唤醒只需要在串口接收程序中判断识别到唤醒指令并调用 audio_recorder_start();
接口即可,下面是一个串口例程:
#include "tal_uart.h"
#include "tal_system.h"
#include "tal_log.h"
#include "base_event.h"
#include "tuya_cloud_types.h"
#include <stdio.h>
#include "audio_recorder.h"
#ifdef ENABLE_WIFI_SERVICE
#include "tuya_iot_wifi_api.h"
#else
#include "tuya_iot_base_api.h"
#endif
#define UART_BOUND 9600
STATIC THREAD_HANDLE my_uart_thread = NULL;
/***********************************************************
***********************typedef define***********************
***********************************************************/
#define ROLE_API "thing.ai.agent.switch.role"
#define API_VERSION "1.0"
typedef struct {
char *commandInfo;
char *description;
} TY_AI_ROLE_T;
/*
*commandInfo\": 是角色 ID,可以在涂鸦开发者平台获取
*/
const TY_AI_ROLE_T POST_CONTENTS[] = {
{"{\"commandInfo\": \"DIY_XEM_EPAXATC0U0W0\"}","小恶魔"},
{"{\"commandInfo\": \"DIY_XTS_EPAXBE3SFRB4\"}","小天使"},
{"{\"commandInfo\": \"DIY_SWK_EPAA4V9THGQO\"}","孙悟空"},
{"{\"commandInfo\": \"DIY_ZBJ_EPA9XXFY2WOW\"}","猪八戒"},
{"{\"commandInfo\": \"DIY_CE_EPA9SDZAXOG0\"}","嫦娥"},
{"{\"commandInfo\": \"DIY_TZ_EPA9NAVSDKAO\"}","唐僧" },
{"{\"commandInfo\": \"DIY_ND_EPAW3QRNEDQ8\"}","牛顿"},
{"{\"commandInfo\": \"DIY_HTL_EPAWROAK5TDS\"}","灰太狼"},
{"{\"commandInfo\": \"DIY_HLBT_EPAWXZXJJG8W\"}","哈利波特"},
{"{\"commandInfo\": \"DIY_KN_EPAX5IQQQOE8\"}","柯南"},
{"{\"commandInfo\": \"SYS_GJXY_EKGXPAQA11J4\"}","杠精小丫"},
};
int g_role_max = sizeof(POST_CONTENTS) / sizeof(POST_CONTENTS[0]);;
/***********************************************************
***********************variable define**********************
***********************************************************/
/**
* @brief http task
* 功能:切换角色
* @param[in] param:Task parameters
* @return none
*/
VOID switch_iot_role(char *role_name)
{
OPERATE_RET rt = OPRT_OK;
ty_cJSON* result = NULL;
CHAR_T *print_data = NULL;
const CHAR_T post_count = sizeof(POST_CONTENTS) / sizeof(POST_CONTENTS[0]);
CHAR_T i;
for(i=0; i<post_count; i++)
{
if(strstr(POST_CONTENTS[i].description,role_name) != NULL) {
break;
}
}
// 检查索引是否有效
if(i >= post_count) {
TAL_PR_ERR("Role not found: %s", role_name);
return;
}
TAL_PR_DEBUG("Processing POST_CONTENT[%u]: %s", i, POST_CONTENTS[i].commandInfo);
// 调用 HTTP POST 函数,传递指定的数组元素
rt = iot_httpc_common_post_simple(ROLE_API, API_VERSION, POST_CONTENTS[i].commandInfo, NULL, &result);
if (NULL == result) {
TAL_PR_DEBUG("result is NULL");
return;
}
print_data = ty_cJSON_PrintUnformatted(result);
if (NULL != print_data) {
TAL_PR_NOTICE("%s", print_data);
ty_cJSON_FreeBuffer(print_data);
print_data = NULL;
}
ty_cJSON_Delete(result);
result = NULL;
return;
}
STATIC VOID __uart0_rev_task(VOID *arg)
{
UINT8_T rx_data[256];
INT_T ret_len=0;
OPERATE_RET rt = OPRT_OK;
int uart_num=TUYA_UART_NUM_0;
while ((1))
{
int cnt=0;
//判断读取超时时间
while(tal_uart_get_rx_data_size(uart_num)<1){
cnt++;
if(cnt>5){
break;
}
tal_system_sleep(10);
}
if(cnt>5) continue;
ret_len = tal_uart_read(uart_num,rx_data,sizeof(rx_data));
char STR[128]= {0};
if(ret_len != 0)
{
TAL_PR_HEXDUMP_DEBUG("UART_RX:",rx_data,ret_len);
if(rx_data[0] == 0xA0 && rx_data[1] == 0x01) {
switch (rx_data[2]) // Assuming rx_data[2] contains the command type
{
case 0x00:
{ /* 哪吒唤醒词 */
sprintf(STR, "哪吒");
break;
}
case 0x01:
/* 猪八戒唤醒词 */
{
sprintf(STR, "猪八戒");
break;
}
case 0x02:
/* 柯南唤醒词 */
{
sprintf(STR, "柯南");
break;
}
default:
break;
}
switch_iot_role(STR);
audio_recorder_start();
// tuya_voice_proto_get_tts_text(STR);//文本对话,将 STR 内容发送到 Agent
TAL_PR_DEBUG("-------------->唤醒词: %s", STR);
}
}
}
tal_thread_delete(my_uart_thread);
my_uart_thread = NULL;
}
OPERATE_RET my_asr_uart_thread(VOID)
{
OPERATE_RET rt = OPRT_OK;
TAL_UART_CFG_T cfg = {0};
cfg.base_cfg.baudrate = UART_BOUND;
cfg.base_cfg.databits = TUYA_UART_DATA_LEN_8BIT;
cfg.base_cfg.stopbits = TUYA_UART_STOP_LEN_1BIT;
cfg.base_cfg.parity = TUYA_UART_PARITY_TYPE_NONE;
cfg.rx_buffer_size = 256;
cfg.open_mode = O_BLOCK;
tal_uart_deinit(TUYA_UART_NUM_0);
TUYA_CALL_ERR_RETURN(tal_uart_init(TUYA_UART_NUM_0,&cfg));//usrt 0 init
THREAD_CFG_T param;
param.priority = THREAD_PRIO_3;
param.stackDepth = 1024*4;
param.thrdname = "my_uart_asr_thread";
TUYA_CALL_ERR_RETURN( tal_thread_create_and_start(&my_uart_thread, NULL, NULL,__uart0_rev_task ,NULL , ¶m));
TAL_PR_DEBUG("======_asr_uart_ task success==============");
return rt;
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈