基于STM32的物联网语音控制智能家居

智能家居

前言

智能家居已经做的很多了,之前用ESP8266做过,今天用STM32做了一个
实物图:
在这里插入图片描述
手机app界面:
在这里插入图片描述
界面我认为还是比较好看的。

一、演示视频

为了提起大家的阅读兴趣,先看演示视频

智能家居

二、代码

语音识别用的LD3320,物联网用的是ESP8266,感兴趣的可以看我之前的文章,之前写过ESP8266的文章。

#include "Reg_RW.h"
#include "LDChip.h"
#include "delay.h"

extern u8 nAsrStatus;
u8  nLD_Mode=LD_MODE_IDLE;
u8  ucRegVal;


/************************************************************************
功能描述: 	 复位LD模块
入口参数:	 none
返 回 值: 	 none
其他说明:	 none
**************************************************************************/
void LD_Reset(void)
{
	RSTB=1;
	delay_ms(5);
	RSTB=0;
	delay_ms(5);
	RSTB=1;
	
	delay_ms(5);
	SCS=0;
	delay_ms(5);
	SCS=1;
	delay_ms(5);
}
/************************************************************************
功能描述: LD模块命令初始化
入口参数: none
返 回 值: none
其他说明: 该函数为出厂配置,一般不需要修改;
					 有兴趣的客户可对照开发手册根据需要自行修改。
**************************************************************************/
void LD_Init_Common(void)
{
	LD_ReadReg(0x06);  
	LD_WriteReg(0x17, 0x35);

	delay_ms(5);
	LD_ReadReg(0x06);  

	LD_WriteReg(0x89, 0x03); 
	delay_ms(5);
	LD_WriteReg(0xCF, 0x43);
	delay_ms(5);
	LD_WriteReg(0xCB, 0x02);
	
	/*PLL setting*/
	LD_WriteReg(0x11, LD_PLL_11);
	if (nLD_Mode == LD_MODE_MP3)
	{
		LD_WriteReg(0x1E,0x00);
		LD_WriteReg(0x19, LD_PLL_MP3_19); 
		LD_WriteReg(0x1B, LD_PLL_MP3_1B);		
		LD_WriteReg(0x1D, LD_PLL_MP3_1D);
	}
	else
	{
		LD_WriteReg(0x1E,0x00);
		LD_WriteReg(0x19, LD_PLL_ASR_19); 
		LD_WriteReg(0x1B, LD_PLL_ASR_1B);
	  LD_WriteReg(0x1D, LD_PLL_ASR_1D);
	}	
	delay_ms(5);
	
	LD_WriteReg(0xCD, 0x04);
	LD_WriteReg(0x17, 0x4c);
	delay_ms(5);
	LD_WriteReg(0xB9, 0x00);
	LD_WriteReg(0xCF, 0x4F);
	LD_WriteReg(0x6F, 0xFF);
}

/************************************************************************
功能描述: 	 LD模块 ASR功能初始化
入口参数:	 none
返 回 值: 	 none
其他说明:	 该函数为出厂配置,一般不需要修改;
					 有兴趣的客户可对照开发手册根据需要自行修改。
**************************************************************************/
void LD_Init_ASR(void)
{
	nLD_Mode=LD_MODE_ASR_RUN;
	LD_Init_Common();

	LD_WriteReg(0xBD, 0x00);
	LD_WriteReg(0x17, 0x48);
	delay_ms(5);

	LD_WriteReg(0x3C, 0x80);
	LD_WriteReg(0x3E, 0x07);
	LD_WriteReg(0x38, 0xff); 
	LD_WriteReg(0x3A, 0x07);
	
	LD_WriteReg(0x40, 0);
	LD_WriteReg(0x42, 8);
	LD_WriteReg(0x44, 0); 
	LD_WriteReg(0x46, 8);
	delay_ms(5);
}

/************************************************************************
功能描述: 	中断处理函数
入口参数:	 none
返 回 值: 	 none
其他说明:	当LD模块接收到音频信号时,将进入该函数,
						判断识别是否有结果,如果没有从新配置寄
            存器准备下一次的识别。
**************************************************************************/
void ProcessInt(void)
{
	u8 nAsrResCount=0;

	ucRegVal = LD_ReadReg(0x2B);
	LD_WriteReg(0x29,0) ;
	LD_WriteReg(0x02,0) ;
	if((ucRegVal & 0x10)&&LD_ReadReg(0xb2)==0x21&&LD_ReadReg(0xbf)==0x35)			/*识别成功*/
	{	
		nAsrResCount = LD_ReadReg(0xba);
		if(nAsrResCount>0 && nAsrResCount<=4) 
		{
			nAsrStatus=LD_ASR_FOUNDOK;
		}
		else
	  {
			nAsrStatus=LD_ASR_FOUNDZERO;
		}	
	}															 /*没有识别结果*/
	else
	{	 
		nAsrStatus=LD_ASR_FOUNDZERO;
	}
		
  LD_WriteReg(0x2b, 0);
  LD_WriteReg(0x1C,0);/*写0:ADC不可用*/
	LD_WriteReg(0x29,0);
	LD_WriteReg(0x02,0);
	LD_WriteReg(0x2B,0);
	LD_WriteReg(0xBA,0);	
	LD_WriteReg(0xBC,0);	
	LD_WriteReg(0x08,1);	 /*清除FIFO_DATA*/
	LD_WriteReg(0x08,0);	/*清除FIFO_DATA后 再次写0*/
}

/************************************************************************
功能描述:  检测LD模块是否空闲
入口参数:	none
返 回 值: 	flag:1-> 空闲
其他说明:	none
**************************************************************************/
u8 LD_Check_ASRBusyFlag_b2(void)
{
	u8 j,i;
	u8 flag = 0;
	for (j=0; j<5; j++)
	{
		i=LD_ReadReg(0xb2);
		if ( i== 0x21)
		{
			flag = 1;						
			break;
		}
		delay_ms(20);		
	}
	return flag;
}
/************************************************************************
功能描述: 	启动ASR
入口参数:	none
返 回 值: 	none
其他说明:	none
**************************************************************************/
void LD_AsrStart(void)
{
	LD_Init_ASR();
}
/************************************************************************
功能描述: 	运行ASR
入口参数:	none
返 回 值: 	1:启动成功
其他说明:	none
**************************************************************************/
u8 LD_AsrRun(void)
{
	LD_WriteReg(0x35, MIC_VOL);
	LD_WriteReg(0x1C, 0x09);
	LD_WriteReg(0xBD, 0x20);
	LD_WriteReg(0x08, 0x01);
	delay_ms( 5 );
	LD_WriteReg(0x08, 0x00);
	delay_ms( 5 );

	if(LD_Check_ASRBusyFlag_b2() == 0)
	{
		return 0;
	}

	LD_WriteReg(0xB2, 0xff);
	LD_WriteReg(0x37, 0x06);
	delay_ms( 5 );
  LD_WriteReg(0x37, 0x06);
	delay_ms( 5 );
	LD_WriteReg(0x1C, 0x0b);
	LD_WriteReg(0x29, 0x10);	
	LD_WriteReg(0xBD, 0x00);
	return 1;
}
/************************************************************************
功能描述: 向LD模块添加关键词
入口参数: none
返 回 值: flag:1->添加成功
其他说明: 用户修改.
					 1、根据如下格式添加拼音关键词,同时注意修改sRecog 和pCode 数组的长度
					 和对应变了k的循环置。拼音串和识别码是一一对应的。
					 2、开发者可以学习"语音识别芯片LD3320高阶秘籍.pdf"中
           关于垃圾词语吸收错误的用法,来提供识别效果。
**************************************************************************/
u8 LD_AsrAddFixed(void)
{
	u8 k, flag;
	u8 nAsrAddLength;
	
	#define DATE_A 14   //数组二维数值
	#define DATE_B 20		//数组一维数值
	
	
	u8 sRecog[DATE_A][DATE_B] = {
																		"ni hao xiao zhi",\
																		"kai deng",\
																		"guan deng",\
		
																		"kai dian shi",\
																		"guan dian shi",\
																		"kai feng shan",\
																		"guan feng shan",\
		
																		"kai re shui qi",\
																		"guan re shui qi",\
																		
		
																		"da kai kong tiao",\
																		"guan bi kong tiao",\
																		"zai jian xiao zhi",\
																 };	/*添加关键词,用户修改*/
	u8 pCode[DATE_A] = {
													CODE_CMD,\
													CODE_DMCS,\
													CODE_CSWB,\
												
													CODE_1KL1,\
		                      CODE_1KL2,\
		                      CODE_1KL3,\
		                      CODE_1KL4,\
		
													CODE_2KL1,\
		                      CODE_2KL2,\
		                      CODE_2KL3,\
		                      CODE_2KL4,\
		
													CODE_3KL1,\
		                      CODE_3KL2,\
													CODE_5KL1,
												};	/*添加识别码,用户修改*/	
	flag = 1;
	for (k=0; k<DATE_A; k++)
	{
			
		if(LD_Check_ASRBusyFlag_b2() == 0)
		{
			flag = 0;
			break;
		}
		
		LD_WriteReg(0xc1, pCode[k] );
		LD_WriteReg(0xc3, 0 );
		LD_WriteReg(0x08, 0x04);
		delay_ms(1);
		LD_WriteReg(0x08, 0x00);
		delay_ms(1);

		for (nAsrAddLength=0; nAsrAddLength<DATE_B; nAsrAddLength++)
		{
			if (sRecog[k][nAsrAddLength] == 0)
				break;
			LD_WriteReg(0x5, sRecog[k][nAsrAddLength]);
		}
		LD_WriteReg(0xb9, nAsrAddLength);
		LD_WriteReg(0xb2, 0xff);
		LD_WriteReg(0x37, 0x04);
	}
    return flag;
}

/************************************************************************
功能描述: 	运行ASR识别流程
入口参数:	none
返 回 值:  asrflag:1->启动成功, 0—>启动失败
其他说明:	识别顺序如下:
						1、RunASR()函数实现了一次完整的ASR语音识别流程
						2、LD_AsrStart() 函数实现了ASR初始化
						3、LD_AsrAddFixed() 函数实现了添加关键词语到LD3320芯片中
						4、LD_AsrRun()	函数启动了一次ASR语音识别流程					
						任何一次ASR识别流程,都需要按照这个顺序,从初始化开始
**************************************************************************/
u8 RunASR(void)
{
	u8 i=0;
	u8 asrflag=0;
	for (i=0; i<5; i++)			//	防止由于硬件原因导致LD3320芯片工作不正常,所以一共尝试5次启动ASR识别流程
	{
		LD_AsrStart();
		delay_ms(5);
		if (LD_AsrAddFixed()==0)
		{
			LD_Reset();			//	LD3320芯片内部出现不正常,立即重启LD3320芯片
			delay_ms(5);			//	并从初始化开始重新ASR识别流程
			continue;
		}
		delay_ms(5);
		if (LD_AsrRun() == 0)
		{
			LD_Reset();			//	LD3320芯片内部出现不正常,立即重启LD3320芯片
			delay_ms(5);			//	并从初始化开始重新ASR识别流程
			continue;
		}	
		asrflag=1;
		break;					//	ASR流程启动成功,退出当前for循环。开始等待LD3320送出的中断信号
	}
	return asrflag;
}

/************************************************************************
功能描述: 	获取识别结果
入口参数:	none
返 回 值: 	LD_ReadReg(0xc5 );  读取内部寄存器返回识别码。
其他说明:	none
**************************************************************************/
u8 LD_GetResult(void)
{	
	return LD_ReadReg(0xc5 );
}

完整的工程代码后面我会上传到我的资源里,需要的可以自行去下载哈。
ESP8266完整代码:


#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT//
#define BLINKER_WITHOUT_SSL      //非SSL加密通信接入,省堆栈  */
#include <Blinker.h>
#include <SoftwareSerial.h>

char auth[] = "8db9e254c6cd"; // blinker app提供的秘钥
char ssid[] = "戚晨夕";// wifi 名字
char pswd[] = "00000000";// wifi 密码
 

// 新建组件对象
BlinkerButton Button1("btn-3qm");//注意:要和APP组件’数据键名’一致
BlinkerButton Button2("btn-nog");//注意:要和APP组件’数据键名’一致
BlinkerButton Button3("btn-3vc");//注意:要和APP组件’数据键名’一致
BlinkerButton Button4("btn-u19");//注意:要和APP组件’数据键名’一致
BlinkerButton Button5("btn-dih");//注意:要和APP组件’数据键名’一致
BlinkerButton Button6("btn-9ju");//注意:要和APP组件’数据键名’一致
BlinkerButton Button7("btn-esp");//注意:要和APP组件’数据键名’一致
BlinkerButton Button8("btn-1fy");//注意:要和APP组件’数据键名’一致
BlinkerButton Button9("btn-lz7");//注意:要和APP组件’数据键名’一致
BlinkerButton Button10("btn-wli");//注意:要和APP组件’数据键名’一致
void button1_callback(const String & state) 
{
    Serial.println("KDLL");

}
 
void button2_callback(const String & state) 
{
    Serial.println("GD");
  
}
void button3_callback(const String & state) 
{
   
    Serial.println("KDS");

}

void button4_callback(const String & state) 
{
   
Serial.println("GDS");
}

void button5_callback(const String & state) 
{
   Serial.println("KKT");

}

void button6_callback(const String & state) 
{
   Serial.println("GKT");

}

void button7_callback(const String & state) 
{
   
Serial.println("KFS");
}

void button8_callback(const String & state) 
{
   Serial.println("GFS");

}

void button9_callback(const String & state) 
{
   Serial.println("KRSQ");

}

void button10_callback(const String & state) 
{
   Serial.println("GRSQ");

}
void setup() 
{
    // 初始化串口,并开启调试信息,调试用可以删除
    Serial.begin(115200); 
    BLINKER_DEBUG.stream(Serial);
    // 初始化blinker
    Blinker.begin(auth, ssid, pswd);
    Button1.attach(button1_callback);
    Button2.attach(button2_callback);
    Button3.attach(button3_callback);
    Button4.attach(button4_callback);
    Button5.attach(button5_callback);
    Button6.attach(button6_callback);
    Button7.attach(button7_callback);
    Button8.attach(button8_callback);
    Button9.attach(button9_callback);
    Button10.attach(button10_callback);
}
 
void loop() 
{
    Blinker.run();
    
}

总结

大概就是这么多了,学无止境,加油。

  • 9
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
# 一、方案名称 基于stm32单片机的宠物自动喂食器 # 二、方案市场分析与前景 * 由于疫情的突发,许多人突发性的被隔离或者是由于其他原因回不了家,家里空荡荡的,回不了家对于家里面有爱宠的"同志们"来说可是一种痛苦,只能活生生的看着爱宠们靠吃猫砂甚至塑料袋来度过,有的还甚至被饿死。而且当今社会中,人们的工作与学习是十分的繁忙,当人们外出时间比较长时对宠物的食物和水的供给就出出现了比较大的问题。特别是当人们出差在外或者是,旅游度假时,经常不能及时的对家中的宠物给予很好地照顾,宠物的饮食常常成为困扰人们主要问题。本装置就是针对此问题而设计的一种装置。他对家居智能化起到了积极地作用,在提高人们生活效率与乐趣的同时,也对人们的出行减少了后顾之忧。 毫无疑问,智能宠物喂食器不仅仅是一款智能设备,它更是连接主人与爱宠的纽带,而功能强大的APP将万千家庭集结到一起,相比单纯的产品,这种基于兴趣、圈子的应用与服务更能打动我们,未来智能宠物喂食器的APP还有很大优化的空间,而且还会基于游戏娱乐的基础之上进一步开拓空间。 # 三、方案使用场所及使用人群 * 使用场所一般是人们所居住的室内,以及一些宠物饲养基地,面向的人群有饲养宠物者其中家中有宠物由于工作原因经常性出差人群是最主要的,还有就是一些大型宠物饲养基地。 # 四、项目具体方案 * 从物联网技术在宠物喂养上的应用出发,研究了一种基于物联网技术的智能宠物投喂器,此投喂器的功能包括对宠物实时或者定时喂食、利用录音和语音提醒宠物进食、残料自动清理等,这些功能利用stm32单片机对系统中的各个特殊功能进行控制,如通过H桥直流电机驱动功能板,直流供电电源板对步进电机下料控制、语言操控模块控制、电动推杆行程控制等,利用MATLAB技术实现了机器学习与对系统稳定性的测试。通过以上功能的结合便能较好的完成对宠物进行远程喂食的功能,实现对宠物的智能投喂,以及通过光电传感器(光电传感器由敏感元件、转换元件、基本电路三部分组成,其主要原理是光电效应。)来监测宠物的实时状况,现在食物平台放置少许食物,当宠物在盛放食物的停留2分钟以上即代表宠物正在进食,该投喂器将继续投喂适量食物,当宠物在平台上待了一段时间后检测器监测到宠物离开以后,投喂器自动将平台清空,并重新放置少许食物,其中传感器采集到的数据通过wifi上传到涂鸦iot平台并在涂鸦app进行显示,主人可在涂鸦app上实现远程投喂,监测喂食器的各种状态。其中投喂器的储存仓里具有保持干燥的装置。 # 五、方案实施流程 ## 准备所需材料 * 语音涂鸦三明治开发套件 * stm32F103最小版 * 光电传感器模块 * 涂鸦iot平台 * 涂鸦app * 步进电机 * 铝型材及符合木板胶枪胶棒各种元器件 ## 实施方案 * 光电传感器模块通过串口与stm32单片机连接,在通过单片机将采集到的的各种数据通过WiFi模块进行上报。 * 串口程序 ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
【RT-Thread作品秀】智能家居语音控制方案。作者:xqyjlj 概述智能家居是现在一个很火热的方向,随着人们生活水平的提高,我们都逐渐开始希望身边的电器都可以不用手来控制,本作品就是基于这种需求,开发出来了一个基于语音控制智能家居方案。本智能家居方案,分为联网与不联网两种版本。其中,无论是联网与不联网,语音识别功能均能正常使用。在本作品没有连上网的情况下,可以进行语音对开关的控制,进行MP3等常用音频文件的播放,以及具有拍照功能,可以将拍下来的照片储存在SD卡内,在本作品连上网的情况下,还附加了以下功能,可以将一些数据上报到云平台(onenet),并且将一些工作日志通过邮件发送给用户。 开发环境硬件:ART_PI(主控) LD3320(语音识别芯片) VS1053(音频解码芯片) OV2640(摄像头) RT-Thread版本:RT-Thread V 4.0.3 开发工具及版本:RT-Thread Studio 2.0.0 RT-Thread使用情况概述内核:调度器,信号量。 组件:UART,DFS,SPI,IIC,PIN。 软件包:smtp_client,btstack,netuils,fal,easyflash,littlefs,onenet。 硬件框架主控:ART-PI ART-Pi 是 RT-Thread 团队为嵌入式软件工程师、开源创客设计的一款极具扩展功能的 DIY 开源硬件。致力打造一个开源的软硬件平台。 语音识别芯片:LD3320 LD3320是非特定人(不用针对指定人)语音识别芯片,即语音声控芯片。最多可以识别50条预先内置的指令。 音频解码芯片:VS1053 VS1053是一款利用SPI通讯的音频解码模块,支持大部分的音频文件的解码播放和编码保存 摄像头:OV2640 OV2640是OmniVision公司生产的一颗1/4寸的CMOSUXGA(1632*1232)图像传感器;支持自动曝光控制、自动增益控制、自动白平衡、自动消除灯光条纹等自动控制功能。 软件框架说明本项目采用的是多级联控模式。将多个模块的任务分为多个级别,以语音识别为主体,摄像头和语音播报为从体,在语音识别到关键字的时候,会出发相对应的函数,实现不同的效果,而onenet是与语音识别互相独立的,会源源不断的把数据实时发送到云端。 软件模块说明smtp_thread_entry:邮件线程,用于发送邮件。 ld3320_asr_thread:语音识别线程,用于语音识别,调用其他程序。 onenet_upload_entry:onenet线程,用于向云端发送数据。 语音识别过程: 首先初始化LD3320芯片,在对其写入需要识别的关键字数据,之后启动LD3320,之后等待其信号引脚拉低,在其信号引脚拉低后,通过读取其寄存器,我们便能知道LD3320获取到了什么样的关键字。之后便从关键字调取我们的相对应的函数。使之工作于不同的功能。 演示效果演示视频: 比赛感悟在报名这个比赛之后,我的目标其实是比现在的功能多得多的,这一点可以从我的Gitee上面的进度表可以看出,奈何原本打算三个人做的项目,到最后,也是我一个人来完成。自己之前画的板子,也是因为自己画板功力不足,还有焊接能力不足,导致本来拥有更多功能的拓展板也没完成。 不过比赛嘛,重要的不是结果,而是过程。通过这次比赛,我最起码收货到了以下知识: 安卓开发,微信小程序设计,web开发(以上由于个人能力问题,其实并未实现),音频处理,STM32H750的众多DMA的设置,以及bootloader,同时也知道了STM32还能片外运行的神奇事情,也学会了RT-Thread Studio的使用。最重要的事情就是明白了不要过分依赖别人,自己想的计划,就要自己去实现,不要总是把任务布置给其他人。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我与nano

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值