• 智能家居环境小护士(原理图、pcb、源码、设计报告)


    目录
    ARM-STM32校园创新大赛 1
    题 目: 智能家居环境小护士 1
    摘要 1
    引言 2

    1. 系统方案 3
      整套系统的工作原理是:单片机是整套系统的控制核心,温湿度传感器负责测试环境中的温湿度;烟雾传感器负责检测空气中的有毒气体,如甲醛和硫氢化物;加湿器负责加湿;当烟雾传感器检测到环境中存在有毒气体时,这个消息被单片机检测到后,单片机就会告诉通讯模块,通讯模块就会发短信通知主人;如果无有毒气体,温湿度传感器测得的温湿度在显示模块上上显示出来,环境中太干时,加湿器就加湿。各个模块各自有各自的任务,互相合作,共同营造一个舒适的环境。 3
    2. 系统硬件设计 3
      2.1温湿度传感器 3
      2.2 烟雾传感器 3
      2.3加湿器 3
      2.4单片机最小系统 3
      2.5 矩阵键盘 3
      2.6 通信模块 4
    3. 系统软件设计 4
      软件调试 4
    4. 系统创新 4
    5. 评测与结论 5
      附录 5

    1.系统方案
    整套系统的工作原理是:单片机是整套系统的控制核心,温湿度传感器负责测试环境中的温湿度;烟雾传感器负责检测空气中的有毒气体,如甲醛和硫氢化物;加湿器负责加湿;当烟雾传感器检测到环境中存在有毒气体时,这个消息被单片机检测到后,单片机就会告诉通讯模块,通讯模块就会发短信通知主人;如果无有毒气体,温湿度传感器测得的温湿度在显示模块上上显示出来,环境中太干时,加湿器就加湿。各个模块各自有各自的任务,互相合作,共同营造一个舒适的环境。
    2.系统硬件设计
    2.1温湿度传感器
    DHT11在整套系统中主要负责对环境中的温度和湿度进行实行检测。
    2.2 烟雾传感器
    烟雾传感器在整个系统中负责检测环境中的有毒气体。
    2.3加湿器
    当环境中温度大于某个数值或者湿度小于某个数值时,加湿器就会加湿。下图是从网上买的加湿器套件,然后再焊接成成品。
    2.4单片机最小系统
    整个系统的控制核心是,数据的发送、接受、显示,通信模块发短信等都是单片机控制的。
    2.5 矩阵键盘
    矩阵键盘是自己焊接的,主要用于设置任何人的电话号码。

    2.6 通信模块
    通信模块主要用于当烟雾传感器检测到有毒气体时,发短信通知主人。
    3.系统软件设计
    软件调试
    前边介绍了系统整体的硬件和软件,下面介绍下软件调试。
    通讯模块不发短信,刚开始感觉很奇怪,感觉自己硬件也没出错,程序应该也没错,但是通讯模块就是不发短信,后来反复检查硬件,加上个小灯,在排除硬件出错的前提下,反复调试软件,终于发短信了:原来是当烟雾传感器检测到有毒气体时,单片机正在执行别的操作,当单片机回来检查烟雾传感器时,那一瞬间已经过去了,所以不会发短信,加上个中断就可以了。
    4.系统创新
    整套系统的创新之处在于其智能:当室内有毒气体浓度大于某个浓度时,报警模块可以发出声音,还可以触动通信模块,发短信通知主人,并且可以设置任意人的电话号码,从而减少一些不必要的损失;还有就是加湿器可以根据温湿度传感器测量的温湿度,选择不同的工作模式进行加湿,这也是体现其智能的原因之一;再有,整套系统可以显著得改善环境,这也是其智能的原因。

    #include"reg52.h"
    #include "uart.c"
    #include "delay.h"
    #include 
    
    //uchar code PhoneNO[]= "18332211268"; //接收方号码
    uchar code PhoneNO[]= "18032837054"; //接收方号码
    uchar code Text1[]= "HOME DOCTOR:Harm gas comes out ,please contact 119";  //内容
    uchar  mq_135_flag;
    uchar DHT11[5],RTflag=0;//读取到得数据校验标志
    uchar  FLAG;   //超时标志位
    uchar  dis_buf;            //显示缓存
    uchar  temp;
    uchar  key;                //键顺序吗
    void delay0(uchar x);      //x*0.14MS
    uchar cdis1[16] = {"  KEY NUMBER   "};
    uchar cdis2[16] = {"  KEY-CODE:   H "};
    uint i;
    
    #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
    
    //I/O定义
    //*********************************************************************/
    sbit LED=P2^0;//定义单片机P1口的第1位 (即P1.0)为指示灯端
    sbit DOUT=P1^1;//定义单片机P2口的第1位 (即P2.0)为气体传感器的输入端
    
    sbit dat=P2^2;//温湿度数据口
    sbit RS=P2^4; //1602读数据
    sbit RW=P2^5;//1602写数据
    sbit EN=P2^6; //1602读写数据使能口
    sbit WET_MOTOR=P2^7;//加湿器控制口
    sbit KEY1=P1^2;//夏天与秋天模式
    sbit KEY2=P1^3;//春天与冬天模式
    sbit KEY3=P1^4;//睡眠模式
    sbit flag_sms=P1^4;//短信输入开始按钮
    //注意在P1口处添加了数字矩阵键盘,不要冲突
    void Delay_t(uint j)
    {      uchar i;
    	    for(;j>0;j--)
    	  { 	
    		for(i=0;i<27;i++);	
    	  }
    }
    void  Delay_10us(void) //10us延时函数
    {
            uchar i;
             i--;
             i--;
             i--;
             i--;
             i--;
             i--;
    }
    void delay(uint z)//1毫秒延时函数
    {
       uint x,y;
       for(x=z;x>0;x--)
        for(y=110;y>0;y--);
    }
    
    /********************************************************
    * INT0中断函数                                          *
    ********************************************************/
    void  mq_135_test(void) interrupt 0 
    {
       EX0=0;
       mq_135_flag=1;     //中断计数  
       EX0=1;
    }
    //
     //	 此下为加湿器动作和模式设置,温湿度显示部分
     //
    void lcd_write_com(uchar com) //1602写指令
    {
       RS=0;
       RW=0;
       EN=1;
       P0=com;
       delay(1);
       EN=0;
    
    }
    void lcd_init()	//1602初始化
    {
    
     
    
    }
    void lcd_write_data(uchar date)//1602写数据
    {
       RS=1;
       RW=0;
       EN=1;
     
       EN=0;
    }
    void write_str(uchar x,uchar y,uchar *s)//在任意地址写符号字母或数字
    {
    	 
    	while(*s)
    	{
    	   lcd_write_data(*s);
    	   s++;
    	}
    
    
    
    }
    void write_shu(uchar x,uchar y,uchar num)//数据显示函数
    {
    	  
    	  uchar s,g;
    	  if(y==0)
    	  lcd_write_com(0x80+x);
    	  else
    	  lcd_write_com(0xc0+x);
    	
    }
    
    uchar scan_key(void)  //注意我暂时没有消抖	也没涉及是否支持多个按下,按键要那种不可以弹上来,要自己控制
    {
     if(KEY1==0)return 1; //夏天与秋天模式
    
    }
    
     void wet_motor(void)//加湿器模式分春天与冬天,夏天与秋天
     {	
     
     //		 DHT11[2]=30;//温度整数
    //		 DHT11[0]=10; //湿度整数   
    		 uchar a;
    		   a=scan_key();
    		   switch(a)
    		   {
    			   case  1:{if( DHT11[0]>5&&DHT11[2]>10)WET_MOTOR=1;};break;//夏天与秋天模式
    			   case 2:{if( DHT11[0]<10&&DHT11[2]>26)WET_MOTOR=1;};break;//春天与冬天模式
    			   case 3:{if( DHT11[0]>5&&DHT11[2]<25)WET_MOTOR=0;};break;// 睡眠模式
    			   default:WET_MOTOR=1;
    			   
    		   }
     }
    
    uchar  write_byte1() //读一个字节
    {
    	   uchar i,comdata,temp1;
           for(i=0;i<8;i++)	   
    	    {
    	   	    FLAG=2;	
    	  
    		 while((dat)&&FLAG++);//flag先与后加1 如果dat一直为1   uchar型变量 flag  溢出变为0  再自加1  
    	   	  
    	   	 if(FLAG==1)break;		//超时则跳出for循环	
             comdata<<=1;//左移一位   高位在前  低位在后
    	   	   comdata|=temp1;
    	     }
    		 return (comdata);  
    }
    void DHT11_5() //读5个字节数据  两个字节为温度数据  两个字节为湿度数据 最后一个字节为校验
    {
    	  uchar i,temp;
    	  //主机拉低18ms 
           dat=0;
    	   Delay_t(180);
    	   dat=1;
    	 //总线由上拉电阻拉高 主机延时20us
    	   Delay_10us();
    	   Delay_10us();
    	   Delay_10us();
    	   Delay_10us();
    	 //主机设为输入 判断从机响应信号 
    	   dat=1;
    	 //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行	  
    	   if(!dat)		 //T !	  
    	  { 
    		FLAG=2;	   //超时标志位
    				 
    		while((!dat)&&FLAG++);//判断从机是否发出 80us 的低电平响应信号是否结束
    			FLAG=2;
    			
    		while((dat)&&FLAG++); //判断从机拉高80us是否结束
    			for(i=0;i<5;i++)//数据接收状态
    			{
    				DHT11[i]=write_byte1();	
    			}		 
    			dat=1;	//释放数据总线  为下一次读取做好准备
                temp=(DHT11[0]+DHT11[1]+DHT11[2]+DHT11[3]);
    			if(temp==DHT11[4])	//数据校验 	
    			{  	   	  
    				RTflag=1;		  
    			}
    			if(RTflag==1) //如果RTflag=1 说明读取到得数据正确
    		   {  			
    				RTflag=0;
    			//	tm[0]=DATARHT[0]/10;
    			//	tm[1]=DATARHT[0]%10;
    			//	tm[2]=DATARHT[1]/10; //湿度
    			  
    			//	tm[3]=DATARHT[2]/10;
    			//	tm[4]=DATARHT[2]%10;
    			//	tm[5]=DATARHT[3]/10; //温度	
    			  
    				write_str(0,0,"NOW-RH: ");//第一行显示湿度
    				write_shu(9,0,DHT11[0]);
    				write_str(11,0,".");
    				write_shu(12,0,DHT11[1]);
    				write_str(13,0,"%");
    				write_str(14,0,"RH");
    				write_str(0,1,"NOW-TE: ");//第二行为显示温度	
    			    write_shu(9,1,DHT11[2]);
    				write_str(11,1,".");
    				write_shu(12,1,DHT11[3]);
    				write_str(13,1,"^");
    			    write_str(14,1,"C");
    				
    				
    //				if(DHT11[3]>=30) 
    //				JIASHI=1;
    //				else 
    //				JIASHI=0;
    								
    		   }
    
    		}
    
    }
    //
    
    //此下代码为矩阵键盘输入数据的相关函数
    //
    /*************************************************************/
    /*                                                           */
    /*  设定显示位置                                             */
    /*                                                           */
    /*************************************************************/
    
    void lcd_pos(uchar pos)
    {                          
      lcd_write_com(pos | 0x80);  //数据指针=80+地址变量
    }
    
    /*************************************************************/
    /*                                                           */
    /* 键扫描子程序  (4*3 的矩阵) P1.4 P1.5 P1.6 P1.7为行        */
    /*							  P1.1 P1.2 P1.3为列             */
    /*                            								 */
    /*************************************************************/
    
     void  keyscan(void)
     { 
     }
    
    /*************************************************************/
    /*                                                           */
    /*判断键是否按下                                             */
    /*                                                           */
    /*************************************************************/
    
     void  keydown(void)
     {  
      	P1=0xF0;
    	if(P1!=0xF0)  //判断按键是否按下 如果按钮按下 会拉低P1其中的一个端口
    	{
    	  keyscan();
        }
     }
    
    void num_key(void) //举证键盘输入数字并显示,先提前测试一下,打算用外部中断来开启这个函数
    {
        uchar m;
        P0=0xFF;                    //置P0口
        P1=0xFF;                    //置P1口  
        delay(10);                 //延时
        //lcd_init();                //初始化LCD             
            
        lcd_pos(0);                //设置显示位置为第一行的第1个字符
         m = 0;
        while(cdis1[m] != '\0')
         {                         //显示字符
           lcd_write_data(cdis1[m]);
           m++;
         }
    
        lcd_pos(0x40);             //设置显示位置为第二行第1个字符
         m = 0;
        while(cdis2[m] != '\0')
         {
           lcd_write_data(cdis2[m]);      //显示字符
           m++;
         }       
    	  dis_buf = 0x2d;          //显示字符"-"
    
        while(1)
        { 
           keydown();
    	   lcd_pos(0x4c);             
           lcd_write_data(dis_buf);        //第一位数显示   
        }
    }
    /********************************************************************
    
    *********************************************************************/
    
    //********************************************************************
    
    
    void main()
    {	
    	//IT0=0;       //低电平触发外部中断0优先级最高
       IT0=1;       //下降沿触发
       EA=1;
       EX0=1;
    
    	lcd_init();	//1602初始化
    	Uart_init(); //串口初始化,
    	delay(100);//等待DHT11温湿度传感器数据稳定  开始激活DHT11 
    	while(1)
    	  {
    			//if(DOUT==0)
    		
    			//delay_ms(30);
    					if( mq_135_flag)
    					{
    						mq_135_flag=0; //标志清零
    
    						SendString("AT+CMGF=1\r\n");	
    						
    						delayms_1000ms();
    						
    						SendString("AT+CSCS=\"GSM\"\r\n");	
    						
    						delayms_1000ms();
    						
    						SendString("AT+CMGS=");	//信息发送指令 AT+CMGS=//
    						SendASC('"');
    						SendString(PhoneNO);   
    						SendASC('"');
    						SendASC('\r');			//发送回车指令//
    						SendASC('\n');			//发送回车指令//
    						
    						delayms_1000ms();
    						
    						SendString(Text1);  
    				
    						delayms_1000ms();
    						
    						SendASC(0x1a);		
    						
    						delayms_1000ms();
    						delayms_1000ms();
    						delayms_1000ms();
    						delayms_1000ms();
    						delayms_1000ms();
    						LED=1;//熄灭P1.0口灯将来改为火警警告声
    
    
    					   for(i==0;i<9;i++)
    
    					   delayms_1000ms();
    
    
    					}
    					else   
    					{
    					LED=0;//点亮P1.0口灯
    				    write_byte1();//读一个字节
      					DHT11_5(); //读数据
    				   	wet_motor();
    				   }
    			
    
    
    //				   if(flag_sms==1)
    //				   num_key();
       	}
     }
    
     
     
    
    
     /*问题:
       每次处理完数据。RsPoint是怎样清零的?????在 准备发一个数据,然后接受一个数据 之前
       RsBuf[RsPoint++]=SBUF;
    		RsBuf[RsPoint]=0x00;   //将下一个数据清零
    
    		如果这个发送没问题。加删除,接收函数,参考桌面上的tc35.c
    
    		添加液晶菜单的支持	,类似手机
    */
     
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    金九银十招聘季, APP测试面试题助你拿高薪Offer
    [vue]在鼠标点击处,画点,并弹窗显示两个点的距离
    序列标注的BIO标注体系
    6.1、Flink数据写入到文件
    奇淫巧技,CompletableFuture 异步多线程是真的优雅
    AI学习指南数学工具篇-PCA基础知识
    MYSQL 存储java.sql.Timestamp类型的数据时,mysql存储时间和java获取到的时间相差8小时
    【趣学算法】Day4 分治算法——二分搜索
    RocketMQ 消息重新投递 解析——图解、源码级解析
    C++STL——vector类与模拟实现
  • 原文地址:https://blog.csdn.net/newlw/article/details/127959479