基于ZigBee的智能家居环境监测系统设计,包括上位机和下位机,附带源码
ARM-STM32校园创新大赛
题 目:基于STM32的智能环境监测系统
摘要 本系统采用stm32f407作为主控芯片,实现对环境的监测。并且通过和手机通信,获取当前的天气预报信息,结合当前测得的温湿度,可以为用户提供出行建议。利用stm32自带的RTC可以实现时间及闹钟功能。此外RTC还可以用于电子日历的制作。从机主控芯片是STM32f103,其主要功能是测取当前的温湿度信息和语音识别。主从机通过nrf24l01无线通信。
1. 引言 科技发展越来越快,我们将要进入物联网的世界。利用已经成熟的温湿度传感器技术,可以获得当前的温湿度信息;利用已经很成熟的光敏传感器技术可以获得当前的光照强度。如果我们将这些信息搜集起来,通过微处理器分析,从而给出控制信息,实现智能控制。我们所要做的事情就是:通过微处理器丰富的外设,来获取周围信息。再分析这些数据,利用自动控制算法,控制外围器件,实现环境的调控。 2. 系统方案 一、温湿度监测模块:1.与数字温度传感器通信,获取当前的温湿度信息。 2.将获得温湿度信息进行滤波处理 3.将温湿度数据打包传送给上位机 4.上位机接受下位机传输数据,将数据解包存储 5.上位机数据分析 该模块中最关键的算法是数据滤波,代码如下:
- #define N 11
-
- char filter()
- {
- char value_buf[N];
- char count,i,j,temp;
- for ( count=0;count<N;count++)
- {
- value_buf[count] = get_ad();
- delay();
- }
- for (j=0;j<N-1;j++)
- {
- for (i=0;i<N-j;i++)
- {
- if ( value_buf[i]>value_buf[i+1] )
- {
- temp = value_buf[i];
- value_buf[i] = value_buf[i+1];
- value_buf[i+1] = temp;
- }
- }
- }
- return value_buf[(N-1)/2];
- }
复制代码
二、光照强度监测模块 本模块比较简单。通过监测光敏电阻两端的电压,来获得电压数据。再将电压数据转化成光照强度数据。检测电压的方法是采用STM32F407的AD模块来实现。同上一个模块一样,要对数据进行滤波处理。算法如上。 三、2.4G无线通信模块 本模块是连接主从机的关键模块。采用的通信芯片是NRF24L01。该芯片内部包括频率发生器、增强型ShockBurst模式控制器、功率放大器、晶体振荡器、调制器、解调器等功能模块。通信接口为SPI,待机电流22uA。 该模块的使用主要是通过对其进行初始化、再选择工作状态(RX/TX)、发送或接收数据。通过软件查询方式,来通信。前期调试时,下位机由于以前调试过,没有遇到什么问题。主要是在STM32F407上由于干接触,还不太了解该SPI库函数的使用方法,犯了一些低级错误。后期调好之后没有出现过大的问题。 蓝牙通行模块是用于与智能手机及电脑通信的。本系统通过该模块与手机通信,获取当前的天气预报信息。此外,还可通过智能手机、电脑等获取本系统当前的信息以及控制本系统。该模块与STM32f407通过USART通信。主要难点是:控制指令是AT指令。由于此前没有学习过该指令,学习该指令花费了几天时间。该模块稳定性高,调试成功后一直没有出现过大的问题。 五、SYN6288合成语音模块 本模块采用USART进行通信。该语音合成芯片,支持多种编码的数据。如:ASIC GBK UTF等。语音合成数据通过打包发送到该模块。 支持多音字及人名的智能识别。该模块控制命令多大几十条,可以很好的实现对输出音量、语速、背景音、多音字识别、强制连读等调控。该模块实现时遇到两个难题:1、多指令的学习使用问题 2、电流干扰问题。第一个问题通过学习该芯片使用手册很快得到了解决。第二个问题的现象是,每当播放语音时,显示屏上就会乱码。经过多次检测,发现问题是该模块播音时电流变化大,对开发板上的电源产生了干扰。解决办法是采用外界电源。 六、语音识别模块LSD3320 本模块基本功能是识别语音,附加功能是播放语音。本模块通过SPI与从机主控芯片通信。从机控制该模块进行语音识别和语音播放。结合fatfs与sdio,可从sd卡上读取MP3数据,从而实现了语音识别MP3播放器。该模块使用时首先初始化,再选择模块工作模式。通过查阅数据手册,可以更好的控制该芯片。结合无线模块可以实现对上位机的控制。结合语音识别功能和语音播放功能可以实现语音对话。
3. 系统硬件设计详细介绍系统各个模块的硬件实现过程,包括电路系统仿真,说明采用关键器件的理由及关键部分的原理图 (不得大量复制原理图和PCB图,更多用框图的方式示意,仅对能体现工作量和创新的部分提供原理图,评委有权对滥用原理图的论文扣分)
语音模块 语音识别模块 无线模块
4. 系统软件设计
5. 系统创新 本系统将主从机分开,利用从机进行语音识别和温湿度监控,主机进行数据分析。通过蓝牙通信,获取智能手机上的天气数据,很好的解决了微控制器连接网路难题。并且,通过蓝牙连接,用户能够使用手机获得当前的温度信息。语音识别功能,增添了更加丰富的人机交互方式。此外,利用开发板上自带的加速度模块,能够实现彩屏的横竖屏切换。 6. 评测与结论
系统的测试分三个阶段,第一个阶段主要是对硬件的测试。包括原理图,焊接等检测。焊接时,分模块焊接、测试。最后,进行整个模块上电测测。 第二个阶段主要是对软件的测试。软件测试也是先分模块测试,再总的进行测试。
第三个阶段是黑盒测试。我们小组内先进行组内测试。通过后,再请其他同学通过使用,发现其中的问题。再进行改进。
进过测试,第一,第二个阶段的测试比较顺利。第三个阶段的测试出现一些问题,主要是语音识别上的问题。通过不断改变算法,最终得到了很好的效果。 附录
STM32单片机源程序如下: - int main(void)
- {
- extern u8 voice7[];
- extern u8 Vscripte1[];
- extern u8 voice7[];
- extern u8 voice1[];
- massage.ScreenMsg=1;
- massage.ScreenMain=1;
- massage.Id=-1;
- massage.Flag=1;
- massage.HardMsg=0;
- massage.Temp1=28;
- massage.Temp2=39;
- massage.Humi1=58;
- massage.Humi2=38;
-
- delay_init();
- LCD_Config();
- Touch_Init();
-
- LCD_Clear(BLUE);
- COM1Init(9600);
- SelfCheck();
- delay_ms(1000);
- My_Init();
- while(1){
- MainMenu();
- }
- }
-
- void My_Init(void){
- extern u8 voice7[];
- extern u8 Vscripte1[];
- extern u8 voice7[];
- extern u8 voice1[];
- u8 i=0;
- u8 Rx_Buf[20];
- LCD_Clear(BLUE);
- GUI_TextV(50,80,"Waitting for data... " ,RED,BLUE,1);
- RX_Mode();
- while(NRF24L01_RxPacket(Rx_Buf));
- if(Rx_Buf[0]==0xda)
- {
- massage.Temp1=Rx_Buf[1];
- massage.Humi1=Rx_Buf[2];
- massage.Temp2=Rx_Buf[3];
- massage.Humi2=Rx_Buf[4];//
- }
- for(i=0;i<11;i++)
- {
- Usart2_Putc(Vscripte1[i]);
- }
- while(Usart2_Getc()==0x4f);
- //联机成功提示音
- for(i=0;i<11;i++)
- {
- Usart2_Putc(Vscripte1[i]);
- }
- while(Usart2_Getc()!=0x4f);
- //开机成功欢迎音
- for(i=0;i<27;i++)
- {
- Usart2_Putc(voice1[i]);
- }
- Touch_Init();
- }
-
- void MainMenuV(void){
-
- GetId();
- switch(massage.Id){
- case 0:
- bluetooth();
- break;
- case 8:
- changeS();
- break;
- case 12:
- monitor();
- break;
- case 13:
- temperature();
- break;
- case 15:
- setting();
- break;
- case 16:
- humidity();
- break;
- case 17:
- voice();
- break;
- case 19:
- speaker();
- break;
- default:
- break;
- }
-
- }
- void MainMenuH(void){
- /*AI_LoadPicFile("0:/JPG/mas.jpg",0,0,240,320);
- delay_ms(800);
- AI_LoadPicFile("0:/JPG/mas1.jpg",0,0,240,320);
- delay_ms(800);
- AI_LoadPicFile("0:/JPG/mas2.jpg",0,0,240,320);
- delay_ms(800);
- AI_LoadPicFile("0:/JPG/mas3.jpg",0,0,240,320);
- delay_ms(800);
- AI_LoadPicFile("0:/JPG/mas4.jpg",0,0,240,320);
- delay_ms(800);
- AI_LoadPicFile("0:/JPG/mas5.jpg",0,0,240,320);
- delay_ms(800);*/
- //RTC_TimeShow();
- GetId();
- switch(massage.Id){
- case 15:
- bluetooth();
- break;
- case 16:
- setting();
- break;
- case 3:
- voice();
- break;
- case 10:
- temperature();
- break;
- case 2:
- //changeS();
- break;
- case 18:
- humidity();
- break;
- case 11:
- speaker();
- break;
- case 19:
- network();
- break;
- case 14:
- nowtime();
- break;
- case 6:
- monitor();
- break;
- case 7:
- calendar();
- break;
- default:
- break;
- }
- slither();
-
-
- }
-
- void sysmas(void){
- if(massage.ScreenMsg==0){
- //GUI_Text(50,80,"Speaker for you " ,RED,BLACK,1);
- }else{
- AI_LoadPicFile("0:/JPG/happ.jpg",0,0,240,320);
- if(massage.HardMsg|0x00){
- GUI_TextV(30,20,"SD working well... ",RED,BLACK,0);
- }else{
- GUI_TextV(30,20,"SD can not work... ",RED,BLACK,0);
- }
- if(massage.HardMsg|0x02){
- GUI_TextV(50,20,"Net working well... ",RED,BLACK,0);
- }else{
- GUI_TextV(50,20,"Net can not work... ",RED,BLACK,0);
- }
- if(massage.HardMsg|0x04){
- GUI_TextV(70,20,"BlueTooth working well...",RED,BLACK,0);
- }else{
- GUI_TextV(70,20,"BlueTooth can not work...",RED,BLACK,0);
- }
- if(massage.HardMsg|0x08){
- GUI_TextV(90,20,"SYN6288 working well...",RED,BLACK,0);
- }else{
- GUI_TextV(90,20,"SYN6288 can not work...",RED,BLACK,0);
- }
- while(!exit_fun("0:/JPG/happ.jpg")){}//end for while
- }
- }
-
- char exit_fun(u8 *path){
- char temp[2];
- extern MSG massage;
- GetId();
- temp[0]=massage.Id;
- delay_ms(100);
- GetId();
- temp[1]=massage.Id;
- if(massage.ScreenMsg){
- //横屏
- //双指收缩
- if((temp[0]==0)){
- if((temp[1]==5)||(temp[1]==1)||((temp[1]==4)))
- {
- turnback(path,"0:/JPG/happbg.jpg");
- //MainMenuH();
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- return 1;
- }
- }
-
- // 单指滑屏
- if((temp[0]==9)){
- if(temp[1]>temp[0]){
- turnback(path,"0:/JPG/happbg.jpg");
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- return 1;
- }
- }else{
- if(temp[0]==10){
- if(temp[1]>temp[0]){
- turnback(path,"0:/JPG/happbg.jpg");
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- return 1;
- }
- }
- }
- }else{
- // 竖屏状态
- // 双指放缩
- if((temp[0]==3)){
- if((temp[1]==2)||(temp[1]==7)||(temp[1]==6))
- {
- turnback(path,"0:/JPG/vappbg.jpg");
- //MainMenuV();
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- return 1;
- }
- }
- // 单指滑屏
- if((temp[0]==6)||(temp[0]==10)||(temp[0]==14)){
- if(temp[1]<temp[0])
- {
- turnback(path,"0:/JPG/vappbg.jpg");
- //MainMenuV();
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- return 1;
- }
- }
-
- }
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- return 0;
- }
-
- void slither(void){
- char temp[2];
- extern MSG massage;
- GetId();
- temp[0]=massage.Id;
- delay_ms(20);
- GetId();
- temp[1]=massage.Id;
- if(massage.ScreenMsg==0)
- {
-
- }else{
- if((temp[0]==5||temp[0]==1)){
- if(temp[1]>temp[0]){
- sysmas();
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- }
- }
- if((temp[0]==13||temp[0]==17)){
- if(temp[1]<temp[0]){
- sysmas();
- temp[0]=0;
- temp[1]=0;
- massage.Id=-1;
- }
- }
- }
- }
复制代码
所有资料51hei提供下载: |