《温湿度检测系统.docx》由会员分享,可在线阅读,更多相关《温湿度检测系统.docx(24页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上DH11数字温湿度测量系统设计1.1.1项目背景介绍随着单片机和传感技术的迅速发展,自动检测领域发生了巨大变化,本文参考了一种基于单片机并采用数字化单总线技术的温度测控系统应用于仓库车间的的设计方案,根据实用者提出的问题进行了改进,提出了一种新的设计方案,在单总线上传输数字信号。即采用DHT11温湿度传感器解决传输模拟量误差大的问题,以及采用高技术的无线收发模块来代替之前大量的电缆,具有更好的经济与实用价值。1.1.1功能要求采用8051单片机和DHT11传感器设计一个数字温-湿度测量系统,温湿度测量范围为-20100相对湿度测量范围为0100%,采用LED数码管显示
2、器,同时二极管作为工作正常指示灯和出错指示灯。1.1.2 硬件电路设计图1.1温湿度检测原理示意图DHT11是一款含有已校准输出的温湿度,它应用专用的数字模块采集技术和温湿度,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测型号的处理过程中要调用这些校准系数。,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为给类应用甚至最为苛刻的应用场
3、合的最佳选择。产品为4针单排引脚封装,连接方便。技术参数供电电压: 3.35.5V DC输 出:数字信号测量范围: 湿度20-90%RH, 温度050: 湿度+-5%RH, 温度+-2分 辨 率: 湿度1%RH, 温度1互 换 性: 可完全互换 ,长期稳定性: 1%RH/年 图1.2DH11通讯过程 图1.3部分硬件1.1.3上位机界面:上位机可方便地实现与单片机之间进行信息传递交互,能够更加容易对执行机构进行控制,实现操作可视化,更加直观,保存重要数据等功能。我们利用VisualBasic6.0(以下简称VB)来编制上位机,VB是一种功能强大、简单易学的程序设计语言。界面是软件和用户交互最直
4、接的层,界面的好坏决定了用户对软件的第一印象, 目前流行的界面风格有三种:单窗体、多窗体一届资源管理器风格,无论是哪种风格以下规则是应该被重视的。易用性,规范性,合理性,美观和协调性,独特性,快捷性,安全性,多窗口的应用与系统资源。1.登录界面设计图1.4温湿度检测系统登录界面设计窗体代码如下:Private Sub Form_Load()Dim I As StringMe.Top = 2500Me.Left = 5000Me.Width = 10000Me.Height = 6500Me.AutoRedraw = TrueEnd SubPrivate Sub Form_Resize()Me.
5、PaintPicture Me.Picture, 0, 0, ScaleWidth, ScaleHeightEnd SubPrivate Sub Command1_Click()If Combo1.Text = zzh And Text2 = zzh123 Then frmMain.Show ElseIf Combo1.Text = zzh3 And Text2 zzh123 Then MsgBox 密码有误或该用户名不存在, vbOKCancel, 提醒! Text2 = End IfEnd SubPrivate Sub Command2_Click()Form1.HideUnload Fo
6、rm1End Sub2.登录界面运行如下图所示:图1.5正常登录界面登录成功后自动跳转到温湿度显示数据监控界面。1.1.4主要上位机子界面及对应代码程序介绍一.温湿度数据监控界面设计监控界面设计思路:(1) 温度湿度实时数据要随时间一起动态显示在文本框中。这样可以及时查看当前温湿度值。(2) 仓库车间内温度变化较湿度变化范围大因此对温度数据应绘制出曲线图以方便了解温度变化趋势并可在需要时利用原始曲线做进一步分析。(3) 同时能将你温湿度值保存下来以便查询,所以设置一个日志管理按钮,通过该按钮切换到日志记录界面查看数据列表。(4) 通讯状态的正常与否关系到数据传输的有效性,因此观测数据的同时需要
7、对照通讯状态,本设计中通信端口设置为1,波特率设置为9600,在数据传输要保证通讯正常,所以设置系统状态显示文本框,只有文本框显示通讯正常,所观测到的数据才有效。(5) 接收采样数据需要以一定频率进行来,所以在界面中设置时钟控件。 图1.6温湿度数据监控界面监控界面显示当前时刻、相对湿度值和摄氏温度值,温、湿度利用DH11模块检测数据并通过单片机I/O口输送到上位机VB的MSComm控件接收。1MSComm控件介绍:MSComm控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能,每个MSComm控件对应于一个串行端口。MSComm控件的主要属性及说明如下。在工具栏中找到“工程”选项里的
8、“部件”,选中MicrosoftCommcontrol6.0,“确定”完成MSComm控件的添加。然后从左边控件工具箱里往窗体添加MSComm控件就可以了,本设计中因为有温度、湿度两组数据需要通信所以添加两个MSComm控件,分别命名为tempMSComm和humiMSComm。图1.7添加MSComm控件点击按钮通过MSComm控件接收下位机数据的程序代码如下:Private Sub cmdReceive_Click()If binReceiveflag ThenfrmMain.cmdReceive.Caption = 开始接收 Else If Not frmMain.tempMSComm.
9、PortOpen Or frmMain.humiMSComm.PortOpen ThenfrmMain.tempMSComm.PortOpen = True frmMain.humiMSComm.PortOpen = True 打开串行口 End If frmMain.tempMSComm.InputLen = 0 frmMain.tempMSComm.InputMode = 0 frmMain.tempMSComm.InBufferCount = 0frmMain.tempMSComm.RThreshold = 1 frmMain.humiMSComm.InputLen = 0 frmMai
10、n. humiMSComm.InputMode = 0 frmMainhumiMSComm.InBufferCount = 0 frmMain. humiMSComm.RThreshold = 1 frmMain.cmdReceive.Caption = 停止接收 End IfbinReceiveflag = Not binReceiveflag2.接收读取数据程序代码Private Sub Timer1_Timer() Dim a As Integer Dim str1 As String Static x As Long Static y As Long Dim y1 As Integer
11、 Text1.Text = Text2.Text = a = 0 Text4.Text = Time$() If tempMSComm.InBufferCount 0 And humiMSComm.InBufferCount 0 Then 程序检查输入缓冲区中是否有数据,若有数据 a = tempMSComm.Input b = humiMSComm.Input End If If a 155 Then t0 = a 100 t1 = t0 10 a = t0 + t1 - 1 Else a = a End If If b 155 Then h0 = b 100 h1 = h0 10 b =
12、h0 + h1 - 1 b = b End If Text1.Text = Str(a) + C 则将此数据读取后,指定给文本框的Text属性 Text2.Text = Str(b) + % y1 = Picture1.ScaleHeight / 2 - (a * Picture1.ScaleHeight) / 200 Picture1.Line (x, y)-(x + (Picture1.ScaleWidth - 600 - Picture1.ScaleLeft) / 60, y1) x = x + (Picture1.ScaleWidth - 600 - Picture1.ScaleLef
13、t) / 60 If x = Picture1.ScaleWidth Then SavePicture Picture1.Image, c:temp.bmp 保存图画,可以根据实际需要命名图片 x = Picture1.ScaleLeft + 300 Picture1.Cls 清屏重画3.温度曲线图图1.2温湿度数据监控界面中右边Fram显示的是温度数据曲线图,出于分析预测温度数据变化趋势的需要,我们在实时显示数据时还应反映历史数据曲线。数据曲线图绘制的程序如下:Picture1.ScaleMode = 1 以VB的基本单位作为建立坐标轴以及绘制图形的单位;Picture1.RefreshPi
14、cture1.CurrentX = Picture1.ScaleWidth - 100Picture1.CurrentY = Picture1.ScaleHeight / 2 - 30Picture1.Print TPicture1.CurrentX = Picture1.ScaleLeft + 20Picture1.CurrentY = Picture1.ScaleTop + 20Picture1.Print C*画纵坐标*For I = Picture1.ScaleLeft + 300 To Picture1.ScaleWidth - 300 Step (Picture1.ScaleWid
15、th - Picture1.ScaleLeft - 600) / 6Picture1.CurrentX = IPicture1.Line (I, Picture1.ScaleTop)-(I, Picture1.ScaleHeight - 300)Picture1.CurrentX = I - 100CurrentY = Picture1.ScaleHeight - 300Picture1.Print (I * 60) (Picture1.ScaleWidth - Picture1.ScaleLeft - 600) - 2Next I*画上半平面的横坐标*For j = Picture1.Sca
16、leTop To Picture1.ScaleHeight / 2 Step (Picture1.ScaleHeight / 2 - Picture1.ScaleTop) / 10)Picture1.CurrentY = jPicture1.Line (Picture1.ScaleLeft + 300, j)-(Picture1.ScaleWidth - 300, j)Picture1.CurrentX = Picture1.ScaleLeft + 80Picture1.CurrentY = jPicture1.Print (Picture1.ScaleHeight / 2 - j) * 20
17、0) (Picture1.ScaleHeight)Next j*画下半平面的横坐标*For k = Picture1.ScaleHeight / 2 To Picture1.ScaleHeight Step (Picture1.ScaleHeight - Picture1.ScaleHeight / 2) / 10)Picture1.CurrentY = kPicture1.Line (Picture1.ScaleLeft + 300, k)-(Picture1.ScaleWidth - 300, k)Picture1.CurrentX = Picture1.ScaleLeft + 80Pic
18、ture1.CurrentY = kPicture1.Print -(k - Picture1.ScaleHeight / 2) * 200) (Picture1.ScaleHeight)Next kEnd Sub 绘制坐标系*Picture1.ScaleMode = 1 以VB的基本单位作为建立坐标轴以及绘制图形的单位;Picture1.RefreshPicture1.CurrentX = Picture1.ScaleWidth - 100Picture1.CurrentY = Picture1.ScaleHeight / 2 - 30Picture1.Print TPicture1.Cur
19、rentX = Picture1.ScaleLeft + 20Picture1.CurrentY = Picture1.ScaleTop + 20Picture1.Print C*画纵坐标*For I = Picture1.ScaleLeft + 300 To Picture1.ScaleWidth - 300 Step (Picture1.ScaleWidth - Picture1.ScaleLeft - 600) / 6Picture1.CurrentX = IPicture1.Line (I, Picture1.ScaleTop)-(I, Picture1.ScaleHeight - 3
20、00)Picture1.CurrentX = I - 100CurrentY = Picture1.ScaleHeight - 300Picture1.Print (I * 60) (Picture1.ScaleWidth - Picture1.ScaleLeft - 600) - 2Next I*画上半平面的横坐标*For j = Picture1.ScaleTop To Picture1.ScaleHeight / 2 Step (Picture1.ScaleHeight / 2 - Picture1.ScaleTop) / 10)Picture1.CurrentY = jPicture1
21、.Line (Picture1.ScaleLeft + 300, j)-(Picture1.ScaleWidth - 300, j)Picture1.CurrentX = Picture1.ScaleLeft + 80Picture1.CurrentY = jPicture1.Print (Picture1.ScaleHeight / 2 - j) * 200) (Picture1.ScaleHeight)Next j*画下半平面的横坐标*For k = Picture1.ScaleHeight / 2 To Picture1.ScaleHeight Step (Picture1.ScaleH
22、eight - Picture1.ScaleHeight / 2) / 10)Picture1.CurrentY = kPicture1.Line (Picture1.ScaleLeft + 300, k)-(Picture1.ScaleWidth - 300, k)Picture1.CurrentX = Picture1.ScaleLeft + 80Picture1.CurrentY = kPicture1.Print -(k - Picture1.ScaleHeight / 2) * 200) (Picture1.ScaleHeight)Next kEnd If*日志管理*Private
23、Sub Cmdrecord_Click()frmLog1.Showfrmlog2.ShowEnd Sub4.温度湿度日志记录界面如前所述,要了解温湿度数据完整变化过程需要对原始数据进行保存并以列表的形式记录。系统运行时从图1.3界面点击“日志管理“按钮即可进入到温湿度日志界面”首先来看温湿度日志记录界面的设计:图1.8温度日志记录上位机界面程序代码如下:Dim no As IntegerPrivate Sub Command2_Click()no = List1.ListIndexList1.RemoveItem noEnd SubPrivate Sub Command3_Click()frm
24、Log1.HideUnload frmLog1End SubPrivate Sub Command4_Click()frmMain.Timer1.Enabled = FalseList1.ClearOpen temp.txt For Input As #1Do While Not EOF(1)Line Input #1, inputdataList1.AddItem inputdataLoopClose #1frmMain.Timer1.Enabled = TrueEnd Sub图1.9湿度日志记录界面程序代码如下:Dim no As IntegerPrivate Sub Command3_C
25、lick()no = List1.ListIndexList1.RemoveItem noEnd SubPrivate Sub Command2_Click()frmlog2.HideUnload frmlog2End SubPrivate Sub Command1_Click()frmMain.Timer1.Enabled = FalseList1.ClearOpen humi.txt For Input As #2Do While Not EOF(2)Line Input #2, inputdataList1.AddItem inputdataLoopClose #2frmMain.Tim
26、er1.Enabled = TrueEnd Sub系统正常运行时的温湿度日志管理界面状态图1.10日志管理界面运行图1.1.5下位机KEIL语言程序 由于时间紧迫DH11模块尚未来得及接通硬件电路,以下的KEIL程序语言实际上是利用18b20测温模块测量温度的程序,供参考。以下是下位机Keil程序语言:#include #include #include#include#define uint unsigned int#define uchar unsigned charsbit DQ = P10; /温度传送数据IO口sbit RS=p11; /湿度传送数据IO口uchar temp_val
27、ue; /温度值uchar TempBuffer5;uchar humi_value;uchar HumiBuffer7/*1602液晶显示部分子程序*/ *Port Definitions*sbit LcdRs= P25;sbit LcdRw= P26;sbit LcdEn = P27;sfr DBPort = 0x80;/P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口unsigned char LCD_Wait(void)LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_();LcdEn=0;return DBPort;/向LCD写入命令或
28、数据*#define LCD_COMMAND0 / Command#define LCD_DATA1 / Data#define LCD_CLEAR_SCREEN0x01 / 清屏#define LCD_HOMING 0x02 / 光标返回原点void LCD_Write(bit style, unsigned char input)LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();/注意顺序LcdEn=1;_nop_();/注意顺序LcdEn=0;_nop_();LCD_Wait();/ *设置显示模*#define LCD_S
29、HOW0x04 /显示开#define LCD_HIDE0x00 /显示关 #define LCD_CURSOR0x02 /显示光标#define LCD_NO_CURSOR0x00 /无光标 #define LCD_FLASH0x01 /光标闪动#define LCD_NO_FLASH0x00 /光标不闪动void LCD_SetDisplay(unsigned char DisplayMode)LCD_Write(LCD_COMMAND, 0x08|DisplayMode);/*设置输入模式*#define LCD_AC_UP0x02#define LCD_AC_DOWN0x00 / de
30、fault#define LCD_MOVE0x01 / 画面可平移#define LCD_NO_MOVE0x00 /defaultvoid LCD_SetInput(unsigned char InputMode)LCD_Write(LCD_COMMAND, 0x04|InputMode);/初始化LCD*void LCD_Initial()LcdEn=0;LCD_Write(LCD_COMMAND,0x38); /8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); /开启显示
31、, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); /清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); /AC递增, 画面不动/液晶字符输入的位置*void GotoXY(unsigned char x, unsigned char y)if(y=0)LCD_Write(LCD_COMMAND,0x80|x);if(y=1)LCD_Write(LCD_COMMAND,0x80|(x-0x40);/将字符输出到液晶显示void Print(unsigned char *str)while(*str!=0)LCD_Write(LC
32、D_DATA,*str);str+;/*ds18b20子程序*/*ds18b20延迟子函数(晶振12MHz )*/ void delay_18B20(unsigned int i)while(i-);/*ds18b20初始化函数*/void Init_DS18B20(void) unsigned char x=0; DQ = 1; /DQ复位 delay_18B20(8); /稍做延时 DQ = 0; /单片机将DQ拉低 delay_18B20(80); /精确延时 大于 480us DQ = 1; /拉高总线 delay_18B20(14); x=DQ; /稍做延时后 如果x=0则初始化成功
33、 x=1则初始化失败 delay_18B20(20);/*ds18b20读一个字节*/ unsigned char ReadOneChar(void)uchar i=0;uchar dat = 0;for (i=8;i0;i-) DQ = 0; / 给脉冲信号 dat=1; DQ = 1; / 给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4); return(dat);/*dh写一个字节*/ void WriteOneChar(uchar dat)unsigned char i=0; for (i=8; i0; i-) DQ = 0;Rs=0; DQ = dat&0
34、x01;RS= dat&0x01; delay_dh11(5); DQ = 1; dat=1; /*读取DS18b201当前温度*/void ReadTemp(void)voidReadHumi(void)unsigned char a=0;unsigned char b=0;unsigned char t=0;unsigned chard=0;unsigned char e=0;unsigned char h=0;Init_dh11();WriteOneChar(0xCC); / 跳过读序号列号的操作WriteOneChar(0x44); / 启动温度转换delay_ds18b20(100)
35、; / this message is wery importantInit_ds18b20();WriteOneChar(0xCC); /跳过读序号列号的操作WriteOneChar(0xBE); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度delay_dh11(100);a=ReadOneChar(); /读取温度值低位b=ReadOneChar(); /读取温度值高位temp_value=b4; void temp_to_str() /温度数据转换成液晶字符显示 TempBuffer0=temp_value/10+0; /十位 TempBuffer1=temp_value%10
36、+0; /个位 TempBuffer2=0xdf; /温度符号 TempBuffer3=C; TempBuffer4=0;void Delay1ms(unsigned int count)unsigned int i,j;for(i=0;icount;i+)for(j=0;j0;delay-) for(i=0;i62;i+) /1ms延时. ; void main(void) unsigned char i; LCD_Initial(); Init_DS18B20() ; UART_Init(); mdelay(3000); while(1) GotoXY(0,0); Print(THE TE
37、MP IS:); ReadTemp(); temp_to_str(); GotoXY(12,0); Print(TempBuffer); /显示温度 for(i=0;i2;i+) SBUF=TempBufferi; /发送数据 while(!TI) TI=0; if(tmp1=0) /检测串口通信状况 GotoXY(0,1); Print(SCOMM IS ERROR) ; else GotoXY(0,1); Print(SCOMM IS OK) ; mdelay(1000); /1秒延时 总结:此次设计参考了徐爱钧 徐阳著的KEIL单片机高级语言应用编程与实践一测温度、湿度的案例,结合自己将数据传输到上位机上的想法,利用VB软件进行了尝试。以上是工作的大半部分,因时间匆忙尚未搭好实物电路运行,不过下位机程序和上位机界面设计一基本完成,其中下位机需要根据温湿度模块对涉及端口传输部分的程序好假修改即可。个人感觉通过短短几天对VB软件已有了基本理解,需要在应用中对相关的函数再多加熟悉,程序编写自感还有些繁琐。希望能有时间将实物作出后再对程序做删减。本次设计的核心思想就是将温度湿度两个重要参数一起实时在PC端
限制150内