专栏名称: 安信可科技
全球领先的联网模组、智能家居等物联网硬件方案提供商。
目录
相关文章推荐
德州晚报  ·  刚刚,杨铭宇黄焖鸡道歉! ·  14 小时前  
德州晚报  ·  太突然!双双宣告停产! ·  17 小时前  
鲁中晨报  ·  最新!王大陆被曝与黑帮勾结 ·  3 天前  
51好读  ›  专栏  ›  安信可科技

【电子DIY作品】+ M61+VC02语音控制HA设备

安信可科技  · 公众号  ·  · 2024-08-09 18:47

正文

智能家居的话,如果只能手动控制会觉得不太智能,如果能用说的或者自动的话体验可能会更好一些。


智能家居其实就是为了给生活添加一些便利,懒人推送科技发展是没错的。

对于个人而言接入智能家居无非有以下几个原因:

1、动动手动动嘴不动腿就是懒恨不能意念控制

2、开关对小朋友不友好,个头不够摸不到开关

3、全屋联动回家模式离家模式等等

基于以上几个原因

通过尝试。实现了语音控制 HA 设备的基本功能。

主要思路如图:

开始想着增加机械开关手动去操作,后来想了以下都语音控制了还要物理开关干嘛呢。

小朋友和老人,直接语音控制开关设备。就很舒服呢。

对于红外设备,还没研究透彻怎么去获取遥控器的红外编码,然后发射出来。这样就可以实现更多的功能。

可以语音控制空调、电视等红外设备。

[智能家居]MQTT 控制 HomeAssistant 设备
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=44644&fromuid=15918
(出处: 物联网开发者社区-安信可论坛)

这里主要还是用到了 HomeAssistant 的自动化功能,这种设置不需要对 HomeAssistant 有很深的了解,简单配置即可。

对于小白用户体验更好一些,上手就用。对于大佬的话,可以延伸出更多的功能。

下面介绍一下主要功能模块

一、离线语音模组系列

VC 系列模组是我司开发的一款 AI 离线语音识别的产品,主芯片是云知声推出的离线语音识别芯片锋鸟 M(US516P6),具有高可靠性,通用性强的特点。在语音识别技术上实现了高可靠的唤醒识别率、更远距离的唤醒、更低误唤醒率、更强的抗噪音能力、更快的响应识别时间,免联网的纯离线识别。

VC 系列模组采用了 32bit RISC 架构内核,并加入了专门针对信号处理和语音识别所需要的 DSP 指令集,支持浮点运算的 FPU 运算单元,以及 FFT 加速器。支持最高 150 条本地指令离线识别,支持 RTOS 轻量级系统,以及简单友好的客制化工具。

VC 系列模组具有丰富的外围接口,包括 UART/I2C/PWM/SPI,以及简单友好的二次开发工具,方便客户实现单模组的语音控制应用场景方案。

VC-02 模组

扬声器功率尽量不要太大,如果用 M61-32S 供电扬声器功率过高会导致掉电。

扬声器:

SPK-8Ω2W
SPK+8Ω2W

官方资料

VC-02 模组规格书: 中文 EN

VC-02 原理图: 点我下载

VC-02 封装: 点击下载

串口烧录工具

定制语音

安信可语音开放平台: http://voice.ai-thinker.com/

在安信可语音开放平台创建产品,选择 VC 系列模组。

然后修改唤醒词

设置 Pin 引脚功能

波特率设置 115200,引脚 B6 设置为 UART1_RX 引脚 B7 设置为 UART1_TX,用来发送接收数据。注意不要配置多个 UART1,否则不生效。

添加语音指令

然后添加控制详情

这里主要用到的就是串口数据,这里发送指令 第一位是指令开头默认 A1,第二位定义的是设备位置,第三位定义的是设备类型,第四位定义的是开关状态,第五位结束位默认 FF。根据自己的需要设置解析即可。

还有免唤醒命令,不用唤醒词直接就可以用,比如开灯、关灯等等。

免唤醒命令词最多 10 个选择自己需要的添加,添多了也是默认取前 10 条。

二、Ai-M61-32S Wi-Fi 模组

Ai-M61 系列模组(下称模组)是由深圳市安信可科技有限公司开发的 Wi-Fi6 & 蓝牙双模模组,搭载 BL618 芯片作为处理器,支持 Wi-Fi 802.11b/g/n/ax 协议和 BLE 5.3 协议。BL618 芯片内置低功耗的 32 位 RISC-V CPU,最高主频可达 320M. 丰富的外围接口,包括 DVP、MJPEG、Dispaly、Audio Codec、USB2.0、SDU、以太网(EMAC)、SD/MMC(SDH)、SPI、UART、I2C、I2S、PWM、GPDAC、GPADC、ACOMP 和 GPIO 等。可广泛应用于音视频多媒体、物联网(IoT)、移动设备、可穿戴电子设备、智能家居等领域。

M61-32S 模组


官方资料

Ai-M61-32S-Kit 开发板规格书: 中文 EN

Ai-M61-32S 开发板原理图: 中文

Ai-M61-32S 模组规格书: 中文 EN

Ai-M61-32S 推荐封装: 点击下载

Ai-M61 系列出厂固件

固件下载工具: 点击下载

固件烧录指南: M61/M62 系列烧录指导(包含模组&开发板)

三、代码部分

主要用 wifi、mqtt、uart、flash

uart 代码主要参考

【完全开源】智能桌面助手——AiPi-DSL_Dashboard
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=42026&fromuid=15918

主程序代码

#include #include #include #include #include #include #include "log.h"#include "board.h"#include "mem.h"
//easy flash#include "easyflash.h"#include "bflb_mtd.h"#include "bl_fw_api.h"#include "wifi_mgmr_ext.h"#include "wifi_mgmr.h"#include "ha_task.h"#include "wifi_event.h"#include "voice_uart.h"
int main(void){ board_init(); wifi_start_firmware_task(); //init easyflash bflb_mtd_init(); easyflash_init(); xTaskCreate(voice_uart_task, "uart task", 1024, NULL, 10, NULL); xTaskCreate(queue_receive_task, "queue_receive_task", 1024*3, NULL, 3, NULL);
vTaskStartScheduler();}


VC02 模组交互代码

5




    
#include #include #include #include #include #include #include #include "ha_task.h"#include "bflb_uart.h"#include "bflb_gpio.h"#include "voice_uart.h"#include "user_mqtt.h"#include "log.h"
#define GBD_TAG "UART"
static void uart_init(void);

extern xQueueHandle queue;uart_rx_cmd_t uart_cmd;static struct bflb_device_s* uart1;static char uart_buff[5] = { 0 };
static const uart_data_t g_uart_buf[] = { {{0xA1, 0x00, 0x01, 0x00, 0xFF}, 5}, //wakeup_uni {{0xA1, 0x00, 0x01, 0x01, 0xFF}, 5}, //openL {{0xA1, 0x00, 0x01, 0x00, 0xFF}, 5}, //closeL};
void voice_uart_task(void* arg){
uart_init(); while (1) { vTaskDelay(1000/portTICK_PERIOD_MS); }}
static int voice_cmd_check(char* buff, int len){
int data_cnt = 0, j = 0; // char* uart_txbuf = pvPortMalloc(4); // memset(uart_txbuf, 0, 4); while (1) { for (size_t i = 0; i < 5; i++) { if (buff[i]==g_uart_buf[j].data[i]) data_cnt++; else break; } if (data_cnt==g_uart_buf->len) break; data_cnt = 0; j++; if (j>23) return -1; } LOG_I("check uart cmd=%d", j); return j;}
static void uart_isr(int irq, void* arg){ uint32_t intstatus = bflb_uart_get_intstatus(uart1); uint32_t rx_data_len = 0; char data_type[1] = { 0 }; if (intstatus & UART_INTSTS_RX_FIFO) { int index = 0; memset(uart_buff, 0, 5); LOG_I("rx fifo\r\n"); while (bflb_uart_rxavailable(uart1)) { uart_buff[index++] = bflb_uart_getchar(uart1); } LOG_I("uart recv:%02X %02X %02X %02X %02X", uart_buff[0], uart_buff[1], uart_buff[2], uart_buff[3], uart_buff[4]); }}/** * @brief **/static void uart_init(void){ struct bflb_device_s* gpio; struct bflb_uart_config_s cfg = { .baudrate = 115200, .data_bits = UART_DATA_BITS_8, .stop_bits = UART_STOP_BITS_1, .parity = UART_PARITY_NONE, .flow_ctrl = 0, .tx_fifo_threshold = 4, .rx_fifo_threshold = 4, };
gpio = bflb_device_get_by_name("gpio"); uart1 = bflb_device_get_by_name("uart1");
bflb_gpio_uart_init(gpio, GPIO_PIN_25, GPIO_UART_FUNC_UART1_TX); bflb_gpio_uart_init(gpio, GPIO_PIN_26, GPIO_UART_FUNC_UART1_RX);
bflb_uart_init(uart1, &cfg);
bflb_uart_txint_mask(uart1, false); bflb_uart_rxint_mask(uart1, false); bflb_irq_attach(uart1->irq_num, uart_isr, NULL); bflb_irq_enable(uart1->irq_num);}



MQTT 与 WIFI

wifi

#include




    
 "FreeRTOS.h"#include "task.h"#include "timers.h"
#include #include #include
#include "bl_fw_api.h"#include "wifi_mgmr_ext.h"#include "wifi_mgmr.h"#include "bflb_irq.h"#include "bflb_uart.h"#include "bflb_l1c.h"#include "bflb_mtimer.h"
#include "bl616_glb.h"#include "rfparam_adapter.h"
#include "board.h"#include "log.h"#include "ha_task.h"#include "config.h"
#define DBG_TAG "WIFI EVENT"
#define WIFI_STACK_SIZE (1024*4)#define TASK_PRIORITY_FW (16)
static wifi_conf_t conf ={ .country_code = "CN",};static TaskHandle_t wifi_fw_task;static uint32_t sta_ConnectStatus = 0;
extern TaskHandle_t https_Handle;/** * @brief WiFi 任务 * * @return int*/int wifi_start_firmware_task(void){ LOG_I("Starting wifi ...");
/* enable wifi clock */
GLB_PER_Clock_UnGate(GLB_AHB_CLOCK_IP_WIFI_PHY | GLB_AHB_CLOCK_IP_WIFI_MAC_PHY | GLB_AHB_CLOCK_IP_WIFI_PLATFORM); GLB_AHB_MCU_Software_Reset(GLB_AHB_MCU_SW_WIFI);
/* set ble controller EM Size */
GLB_Set_EM_Sel(GLB_WRAM160KB_EM0KB);
if (0 != rfparam_init(0, NULL, 0)) { LOG_I("PHY RF init failed!"); return 0; }
LOG_I("PHY RF init success!");
/* Enable wifi irq */
extern void interrupt0_handler(void); bflb_irq_attach(WIFI_IRQn, (irq_callback)interrupt0_handler, NULL); bflb_irq_enable(WIFI_IRQn);
xTaskCreate(wifi_main, (char*)"fw", WIFI_STACK_SIZE, NULL, TASK_PRIORITY_FW, &wifi_fw_task);
return 0;}/** * @brief wifi event handler * WiFi 事件回调 * * @param code*/

void wifi_event_handler(uint32_t code){
sta_ConnectStatus = code;
switch (code) { case CODE_WIFI_ON_INIT_DONE: { LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_INIT_DONE", __func__); wifi_mgmr_init(&conf); } break; case CODE_WIFI_ON_MGMR_DONE: { LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_MGMR_DONE", __func__);
} break; case CODE_WIFI_ON_SCAN_DONE: { char* scan_msg = pvPortMalloc(128); wifi_mgmr_sta_scanlist(); LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_SCAN_DONE SSID numbles:%d", __func__, wifi_mgmr_sta_scanlist_nums_get()); sprintf(scan_msg, "{\"wifi_scan\":{\"status\":0}}"); vPortFree(scan_msg); } break; case CODE_WIFI_ON_CONNECTED: { LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_CONNECTED", __func__); void mm_sec_keydump(); mm_sec_keydump(); } break; case CODE_WIFI_ON_GOT_IP: {
LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_GOT_IP", __func__); mqtt_client_init(MQTT_HOST, MQTT_PORT); mqtt_client_register_event(); vTaskDelay(500/portTICK_PERIOD_MS); mqtt_start_connect(MQTT_HOST, MQTT_PORT, MQTT_USERNAME, MQTT_PASSWORD); mqtt_app_subscribe("sub", 0); } break; case CODE_WIFI_ON_DISCONNECT: { LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_DISCONNECT", __func__);
} break; case CODE_WIFI_ON_AP_STARTED: { LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_AP_STARTED", __func__); } break; case CODE_WIFI_ON_AP_STOPPED: { LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_AP_STOPPED", __func__); } break; case CODE_WIFI_ON_AP_STA_ADD: { LOG_I("[APP] [EVT] [AP] [ADD] %lld", xTaskGetTickCount()); } break; case CODE_WIFI_ON_AP_STA_DEL: { LOG_I("[APP] [EVT] [AP] [DEL] %lld", xTaskGetTickCount()); } break; default: { LOG_I("[APP] [EVT] Unknown code %u ", code); } }}
uint8_t wifi_connect(char* ssid, char* passwd){






请到「今天看啥」查看全文