智能家居系统设计(裸机stm32/μCOS-III)
时间:2022-10-12 08:00:01
智能家居系统设计[裸机stm32/μCOS-III]
??在正式解释之前,让我们总结一下。该项目整合了大学所学的一些知识,这也是我大学的毕业设计,也是对大学的解释。
??首先,让我们来谈谈项目实现了哪些功能,以便每个人都能理清自己的想法。该项目有语音识别、触摸屏、小程序四种控制方法APP,控制对象是家用电器(这里使用多路继电器模拟家用电器)。
??这四种控制方法还可以反馈收集的数据:
??在语音识别方面,在语音模块识别到特定的关键字后,通过语音广播模块反馈收集到的温度和湿度数据;
??在触摸屏和APP另一方面,在触摸屏上显示收集到的温度和湿度、有害气体浓度和光强度,也可以设置湿度和有害气体浓度的阈值(湿度阈值设置为当湿度超过设定阈值时,表示室外下雨,让窗户自动关闭(也使用继电器模拟窗户的开关);当浓度超过设定阈值时,设置有害气体浓度阈值,表明室内有害气体浓度过高,语音广播"煤气含量过高,请及时处理"来达到警示的目的),最后还能设置是否开启安防模式,在安防模式下,会通过人体感应模块不断检测周围是否有人,如果有人的话,蜂鸣器就会报警警示,同时在APP相应的图标也会在小程序上改变。
??除了显示收集到的数据和控制电器外,小程序还可以显示当地的天气状态。
APP远程控制可以参考我之前写的文章:stm32 esp8266 onenet平台
小程序的远程控制可以参考我之前写的文章:stm32利用mqtt通信小程序
语音识别的控制可以参考我之前写的文章:stm32利用语音识别和广播智能控制led灯
控制触摸屏可参考淘晶驰官方文件:USART HMI资料中心
本项目使用的设备如下:
STM32F103ZET6最小系统板
ESP8266-01S模块(2,一APP,一个用于小程序)
USB转microUSB数据线
DHT11温湿度
MQ-5模块
光敏电阻模块
HC-SR505人体感应模块
BEEP蜂鸣器
语音识别与广播模块(亚博智能)
串口触摸屏(淘晶驰X3系列 4.3寸)
为了让大家对设备的位置有更深入的了解,这里用soliwork画一个三维理想模型,清楚地显示了设备的具体位置。如下图所示:
因为这个项目需要很多线连接,如果用杜邦线连接,会很麻烦,所以为了简化接线,这里画了一块PCB板替代杜邦线,整体效果也美观多了。如下图所示:
本项目的接线定义如下:
/* 接线定义 ESP8266(APP) DHT11 MQ-5 光敏电阻 HC-SR505 BEEP(有源,低电平触发) TX->stm32 RX(PA3) VCC->stm32 3.3V VCC->stm32 5V VCC->stm32 5V VCC->stm32 5V VCC->stm32 3.3V RX->stm32 TX(PA2) GND->stm32 GND GND->stm32 GND GND->stm32 GND GND->stm32 GND GND->stm32 GND 3.3V->stm32 3.3V DATA->stm32 PF12 AO->stm32 PA1 AO->stm32 PA4 AO->stm32 PF13 AO->stm32 PF14 GND->stm32 GND 语音识别模块 语音合成广播模块 串口屏 ESP8266(小程序) IIC1 IIC2 TX->stm32 RX(PD9) TX->stm32 RX(PC11) VCC->单片机5V VCC->单片机5V RX->stm32 TX(PD8) RX->stm32 TX(PC10) SCL->单片机PB8 SCL->单片机PB10 5V->stm32 5V 3.3V->stm32 3.3V SDA->单片机PB9 SDA->单片机PB11 GND->stm32 GND GND->stm32 GND GND->单片机GND GND->单片机GND */
让我们来看看设计页面效果图:
APP界面设计:
小程序界面设计:
触摸屏界面设计:
然后附上录制的相关视频:
1.小程序登录
2.语音识别(有声)
3.数据采集
4.按键控制
5.安全检测(有声)
最后附上32程序的主代码:
#include "stm32f10x.h" #include "onenet.h" #include "esp8266.h" #include "delay.h" #include "usart.h" #include "serial.h"
#include "led.h"
#include "dht11.h"
#include "adc.h"
#include "hc-sr505.h"
#include "beep.h"
#include "bsp_i2c.h"
#include "esp8266_mqtt.h"
#include "onenet_mqtt.h"
//C库
#include
#include
//网络卡导致发送到云平台的速度变慢
/* 接线定义 ESP8266(APP) DHT11 MQ-5 光敏电阻 HC-SR505 BEEP(有源,低电平触发) TX->stm32 RX(PA3) VCC->stm32 3.3V VCC->stm32 5V VCC->stm32 5V VCC->stm32 5V VCC->stm32 3.3V RX->stm32 TX(PA2) GND->stm32 GND GND->stm32 GND GND->stm32 GND GND->stm32 GND GND->stm32 GND 3.3V->stm32 3.3V DATA->stm32 PF12 AO->stm32 PA1 AO->stm32 PA4 AO->stm32 PF13 AO->stm32 PF14 GND->stm32 GND 语音识别模块 语音合成播报模块 串口屏 ESP8266(小程序) IIC1 IIC2 TX->stm32 RX(PD9) TX->stm32 RX(PC11) VCC->单片机5V VCC->单片机5V RX->stm32 TX(PD8) RX->stm32 TX(PC10) SCL->单片机PB8 SCL->单片机PB10 5V->stm32 5V 3.3V->stm32 3.3V SDA->单片机PB9 SDA->单片机PB11 GND->stm32 GND GND->stm32 GND GND->单片机GND GND->单片机GND */
/* 初始化阶段不要说话,防止被语音识别到,导致语音识别卡住 */
/* 发送数据给服务器端,如果没有应答,可能是因为服务器不稳定,过段时间就好了 */
/* 在开发过程中发现,有时候明明只延时了10ms但是实际上延时了足足100ms(多了十倍), 其原因可能是: 1、外部HSE没起震,结果使用的是内部HSI,这种情况下,默认的是没有倍频的。 实际时钟速度就变成了8MHZ,而不是72MHZ,所以时间相差了接近10倍。 解决方法是重新复位,直到他外部晶振起震 2、语音识别模块使用的硬件IIC干扰到晶振的正常运行,可能是硬件设计电路的问题, 如果要想正确延时的话,必须关闭语音识别模块,若想要打开语音识别模块,则会加长延时时间 */
extern SendData sendata;
extern unsigned short esp8266_cnt;
const char *devSubTopic[] = {
"/iot/1009/zsd1"}; //适用EMQX(无需主题前缀)、杰叔叔服务器(需要指定前缀)
const char *devPubTopic = "/iot/1009/zsd2"; //适用EMQX(无需主题前缀)、杰叔叔服务器(需要指定前缀)
void Hardware_Init(void) //各种功能器件的初始化
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断控制器分组设置
delay_init(); //systick初始化
Usart1_Init(115200); //串口1,打印信息用
Usart2_Init(115200); //串口2,驱动ESP8266用于APP
Usart3_Init(); //串口3,与串口屏通信进行数据交互
Uart4_Init(115200); //串口4,驱动ESP8266用于小程序
LED_Init(); //LED灯初始化
Device_Init(); //继电器六个IO的初始化
HC_SR505_Init(); //人体感应模块初始化
Beep_Init(); //蜂鸣器初始化
Adc_Init(); //ADC初始化
while(DHT11_Init()) //DHT11初始化
delay_ms(200);
UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");
}
int main(void)
{
char array[256]; //将要发布主题的数据存储区
unsigned char *dataPtr_mqtt = NULL; //接收MQTT数据的数据包指针
unsigned short timeCount = 0; //发送间隔变量
unsigned char *dataPtr = NULL; //存储接收到的数据
u8 i = 0; //LED灯闪烁计数位
u8 j = 0; //ESP8266(APP)复位计数位
bool flag = 0; //LED取反标志位
Hardware_Init(); //初始化外围硬件
ESP8266_Init(); //初始化ESP8266(APP)
ESP8266_Init_MQTT(); //初始化ESP8266(小程序)
while(OneNet_DevLink()) //接入OneNET服务器
delay_ms(500);
while(OneNet_DevLink_MQTT()) //接入EMQX服务器
delay_ms(500);
OneNet_Subscribe(devSubTopic, 1); //MQTT的订阅主题
voice_module(); //语音模块初始化
while (1) {
if (++timeCount > 3) {
//下面ESP8266_GetIPD函数执行完需要70-100ms的时间,这里计数30,表示大约3s发送一次数据;如果外部晶振不起作用,这里就设置为3也就是3s
//UsartPrintf(USART_DEBUG, "data:%d\r\n",esp8266_cnt); //判断串口2是否有数据接收到
DHT11_Read_Data(&sendata.temp,&sendata.humi); //读取温湿度值
get_ppm_lx(&sendata.ppm, &sendata.lx); //获取煤气ppm、光强lx,这个函数大概花费50ms
deal_with(); //判断湿度、煤气含量是否超阈值
OneNet_SendData(); //发送数据给云平台
sprintf(array, "{\"temp\":%.1f,\"humi\":%.0f,\"light\":%.1f,\"ppm\":%.0f,\"led1\":%d,\"led2\":%d,\ \"win\":%d,\"cur\":%d,\"fan\":%d,\"cook\":%d,\"sec\":%d,\"sec_image\":%d}", \
sendata.temp, sendata.humi, sendata.lx, sendata.ppm, sendata.light1, sendata.light2, sendata.window\
, sendata.curtain, sendata. fan, sendata.rice_cooker, sendata.security, sendata.detect);
OneNet_Publish(devPubTopic, array); //MQTT的发布主题
memset(array, 0, sizeof(array));
//发送数据给串口屏
Screen_SendData(sendata.temp, sendata.humi, sendata.ppm, sendata.lx);
timeCount = 0;
//ESP8266_Clear(); //清除esp8266_buf中的数据
}
speech_recognition(sendata.temp, sendata.humi); //判断是什么指令并给出相应的回应
data_handle(); //对串口返回的数据进行处理
if (sendata.security == 1) {
//安防模式开启
if (HC_SR505 == 1) {
//感应到人
sendata.detect = 1;
beep = 0; //蜂鸣器响
} else if (HC_SR505 == 0) {
//感应不到人
sendata.detect = 0;
beep = 1; //蜂鸣器不响
}
} else if (sendata.security == 0) sendata.detect = 2; //安防模式关闭
//若延时正常,这里设置等待的时间为10*10ms=100ms,确保进入一次函数后能收到数据,如果返回NULL,表示暂时接收不到数据
//若延时不正常,这里可以设置等待1*10ms,虽然会使得数据在下一次才接受到,不过程序运行很快,这种的话会实时响应其他的程序代码,这里延时大概是50ms
dataPtr = ESP8266_GetIPD(10);
if(dataPtr != NULL){
OneNet_RevPro(dataPtr);
j=0;
}
dataPtr_mqtt = ESP8266_GetIPD_MQTT(1);
if(dataPtr_mqtt != NULL)
OneNet_RevPro_MQTT(dataPtr_mqtt);
i++;
j++;
if (i > 3) {
//这里计数10,表示1秒;如果外部晶振不起作用,这里计数1,表示1秒;如果进入此判断LED闪烁一次,表示系统正常运行
i = 0;
flag = !flag;
LED0(flag);
}
if(j > 12){
//这里计数160,表示16秒;如果外部晶振不起作用,这里计数16,表示16秒;如果进入此判断表明设备掉线,需要重新连接
ESP8266_Init(); //这里需要等待几分钟,要等到WIFI模块彻底断开连接后,串口才会接收到WIFI模块的AT指令返回值
OneNet_DevLink();
j = 0;
}
}
}
这里主要给大家列出main程序,几乎每个函数后面都有相应的注释,里面嵌套的函数也有相应的注释,由于函数过多,这里就不一一列举出来。该项目采用BSP工程管理的思想来进行模块化,方便代码的维护。如下图所示:
本项目具体的执行流程如下图所示:
上面只是给大家提供一个大概的思路,希望对大家能有所启发。在制作该项目过程中,考虑到实时性问题,将原来裸机的代码移植到μCOS-III中,从而来提高系统的响应。
附上整个智能家居项目代码链接:智能家居系统设计(stm32/μCOS-III)
代码要的下方留言邮箱我会第一时间发给你们的,有什么问题也可以下面评论!(其中包含裸机stm32和μCOS-III两个版本)