摘要
随着社会竞争压力越来越大,人们迫切想要提高自己的竞争能力,而提高学历就是最有效的方式之一,而学校
学生数量的激增,就带来了很多治理问题,尤其是教室安全问题。本毕业设计是以STC89C52单片机为MCU,通过硬件
电路与软件代码结合来采集周围环境信息,再将信息通过串口通信传输ESP8266中,再通过贝壳物联提供的平台将同
步到手机App中,解决教室安全监控问题。
本毕业设计主要分为三块:一、数据采集部分,该部分以STC89C52为MCU通过外围采集模块,采集教室的温度、
湿度、烟雾以及人员出入情况的数据;二、联网数据传输部分,联网分为手机联网与ESP8266联网,数据传输是借助
贝壳物联提供的平台进行数据传输。ESP8266需要先连接WIFI才能登上贝壳物联平台才能传输数据;三、App监控部
分,利用贝壳物联提供的平台,通过ESP8266实现将数据传输到使用HBuilder编程的手机App上与控制室内灯。
本设计实现了硬件电路与软件的设计,完成预期设想的数据采集、数据传输、指令下达与实现等功能。本设计
不仅有很强的实用价值和良好的市场前景,还有很强的功能扩展空间。
关键词:ESP8266 DHT11 手机App MQ-2
1.绪论
1.1研究背景与意义
在社会竞争如此激烈的现代,为了提高自己或自己孩子在社会的竞争力,提高学历无疑是最有效的方法之一,
这也导致我国在校大学生总数超过4000万,且逐年增加。相应教室安全问题就开始越发尖锐,教室各项安全防范工
作难度也越来越困难。而防范工作的重中之重就是教室防火、防盗,教室大功率电器的使用与吸烟是教室火灾的最
要原因,大学生的增加也增加了教室盗窃事件。
长时间以来,大部分学校都是使用传统的人工排查教室的安全易患,这种方式存在许多缺点,如:繁琐、效率
低下、时效性低。如果在教室内安装摄像头不仅容易侵犯学生隐私而且执行成本过高,都不利于在教室推广。
针对传统的教室安全监控,效率低、时效性差等缺点,安装摄像头又易侵犯学生隐私、成本过高等缺点,我设
计的基于STC89C52的教室安全监控系统设计能够使之完善,更加方便快捷的实现对教室安全的监控,更好的为广大
师生服务。
1.2国内外研究现状
1.2.1国外研究现状
目前为止国外的教室管理智能化水平相较于国内比较先进。比如西门子楼宇科技公司研发的Guarto Easy系
统, 这个系统就是在充分了解学校教室管理的情况下,推出的一种总线式结构的新型教室安全防范系统。这个新型
教室安全防范系统将视频监控、音频对讲监听、防盗报警(有线或无线连接方式)、火灾探测、危险气体探测等多种
警告方式(声光、无线、拨号)结合起来,同时还能监测学生的进出情况,对学生教室进行全方位的安全防范。经过
国外某知名大学的科学院科研人员研究发现,该新型教室安全防范系统用到的传感器有摄像头传感器、烟雾检测
器、声音传感器、光敏电阻传感器、气体探测传感器、麦克风传感器、高强度蜂鸣器以及通信模块,能将多种传感
器进行相互协作,可见这个安全防范系统对于当时的科技发展情况而言是多么的先进,所以当时这个系统出世的时
候,国外各大高校都争相引进这个教室安全防范系统,对高校教室学生的安全管理起到了至关重要的作用,可见国
外各个提供住宿的学校对于学生的住宿安全问题是多么的重视。
目前为止国外,教室安全防范系统在国外的研究依旧局限于基于这个系统的范围之内,尚未有更大的突破。
1.2.2国内研究现状
目前国内,对于教室安全监控方面大部分学校采用在教室走廊里安装摄像头对教室进行监管,由学校学生会组
织对教室违禁电器、夜不归宿等不定期的突击检查,还有教室管理员对教室学生的管理等方式来预防教室里的突发情况。但是这种教室管理方式存在诸多缺点,例如:摄像头监控只能监控教室走廊不能监控到每个教室内的情况,
但如果每个教室都安装摄像头这不仅仅要消耗大量的精力与财力,而且这无法保证教室学生的隐私,在现代社会个
人隐私是十分重要的;学生会的突击检测效率低而且不能精准反应教室内的隐藏易患;同时这些教室监控方式都通
病就是时效性低,不能第一时间掌握教室安全动向。
随着无线网络通信技术与自动控制技术的快速发展,无线网络通信技术与自动控制技术的应用被广泛的应用到
我们的生活。例如“小米的智能家居”,便是使用无线网络通信技术与自动控制技术通过家庭无线网络,便能轻松
实现对家电的远程访问和控制[1]。而这些技术便是对教室安全监控系统开发最有力的支持。
现在国内,在这些技术的强力支持下各式各样更加智能的教室监控开始如雨后春笋一样不断涌现,这些教室安
全监控设计主要包含火灾报警、烟雾报警等[2]。智能化教室也将不作为一个单独的个体系统,而是成为学校所有智
能化的一个部分,使整个学校成为一个整体组成智能化校园[3]。但要普及需要时间。
1.3课题的主要内容
本设计是以STC89C52为主芯片,ESP8266为从芯片设计的教室安全监控系统。STC89C52用来采集数据与执行手机
App指令,ESP8266负责STC89C52采集的数据与手机指令的联网传输。
本设计主要内容如下:
通过温湿传感器采到的教室据送到STC89C52芯片中对数据进行处理,并将处理好的数据显示于LCD1602上面,
当室内温度超过设定的阈值时,蜂鸣器会报警;待到环境温度降到低于阈值的时候,蜂鸣器报警会自动关闭。
使用两个光电开关判断教室人员出入情况,显示在液晶显示器LCD1602上,配合校园监控系统,既能保证学生财
产安全也尊重学生隐私。
3.采用烟雾探头传感器来检测教室环境的烟雾含量,该烟雾探头传感器使用数字量传入STC89C52芯片,通过电位器
来调节对各种危险气体敏感程度,如有教室内的浓度超出设定阈值,蜂鸣器会自动报警。
4.将单片机采集到的数据,先通过串行通信传入ESP8266,然后使用ESP8266对数据进行处理,最后ESP8266再将数据
传输到手机App上显示。
5.手机App可以通过ESP8266控制教室灯的亮灭和总闸的开关。
2系统总体设计
2.1功能概述
本毕业设计主要功能可分为烟雾检测部分、温湿度检测部分、App监控部分、光电开关检测人员出入部分、
LCD602液晶显示器五个部分。系统结构图如图2.1所示。
设计涉及主硬件为:STC89C52单片机、STC89C52单片机最小系统板、DHT11温湿度传感器、MQ-2烟雾传感器、
ESP8266模块、LCD1602液晶显示模块、蜂鸣器报警模块、继电器模块、LED灯、光电开关等。
图2.1 系统结构图
2.2设计方案
2.2.1传感器的选择
本设计需要检测的数据有温度、湿度以、烟雾浓度以及出入检测。
针对教室的温度和湿度数据采取我设计两种方案:一、利用DS18B20温度传感器采集教室室内的温度数据[5] 。
利用HS1101电容式湿度传感器来采集教室湿度数据;二、选用DHT11同时可以同时采集教室内的温湿度的数据[6]。
本着节约串口资源为之后的功能预留更多的串口资源的思想,所以选择第二种方案。
烟雾传感器的选择的两种方案:一、气敏式烟雾传感器,这类传感器使用在清洁空气中导电率较低的半导体制
成[7]。当检测空气中的烟雾浓度上升时,半导体的导电率也随之增强,从而触发警报;二、离子式烟雾传感器,内
设置一个电离室,当烟雾粒子进入电离室,就会改变电离室的电离状态,从而触发报警[8]。对比两类烟雾传感
器, 在火灾报警这方面,离子式烟雾传感器要优于气敏式烟雾传感器,但气敏式烟雾传感器胜在探测种类多,不仅
仅可以用于火灾报警还可以对其他危险气体发出报警,所以我选择了MQ-2气敏式烟雾传感器。
出入检测选择我选择使用两个E18-D80NK-N传感器来完成这一功能。该传感器通过发射光信号接触到障碍物后反
射被接收端接受到输出低电平,可以调节上面的电位器来调节感应距离[9]。
2.2.2数据传输方式选择
方案一:选择SIM900A进行联网传输数据 SIM900A模块是由GSM通信模块与GPRS通信模块紧凑的组合在一起。其
中的GSM通信模块只能用来短信的形式传输
数据。而相比于GSM通信,GPRS通信不仅仅可以传输内容形式上多种多样,如视频、上网等等,而且在单位时间
内传输速度要比GSM通信快的多。同时GPRS通信对信道的利用率也要比GSM通信快,但如果只是传输少量的数据的
话,GSM 通信要比GPRS通信要低许多[10]。
方案二:选择ESP8266进行联网传输数据
ESP8266是一个十分灵活的芯片,自带TCP/IP协议,可以作为无线接入点使用,可以作为无线终端也可以即作为
无线接入点有作为无线终端。我们能将ESP8266作为无线接入点连接到教室的WIFI上,实现ESP8266往云端服务器进
行数据传输[11-12]。如果我们使用手机与云平台连接,就能使用手机通过云平台向ESP8266发送数据,也能接受数
据。
ESP8266开发方式众多开发便利、价格低、传输距离远等优点。ESP8266在芯片上集成了强大的片上处理能力与
存储能力,可以通过烧录不同的固件,将ESP8266当作独立的MCU。主要的缺点就是ESP8266使用的3.3V电平,不支持
一些5至3V逻辑的改变,所以与单片机STC89C52一起使用要使用两种电源供电。
这两个方案比较差别在于SIM900A是可以通过安装SIM卡来实现数据传输,而使用SIM手机卡就会提高本设计的成
本,不利于在教室推广。ESP8266需要连接WIFI来传输数据,在现在大学生教室WIFI已经是必备之物,所以ESP8266
符合我的预期。
2.2.3手机App开发方式选择
现在主流的APP开发方法有三种:Native App:本地应用程序、Web App:网页应用程序、Hybrid App:混合应用程
序
首先是Native App开发,这种开发方式是Android官方或iOS官方推出的程序开发工具开发。现在市场上大部分
手机App都是使用这种方式开发。使用这种开发方式的优势:性能稳定;开发的App可实现的功能多种多样且上限极
高;操作流畅且反应速度快。同时这种开发方式也有明显的缺点:开发周期长;开发成本高,维护成本高,更新缓
慢;同一款App不能同时再不同手机系统运行无法实现跨平台安装。
其次是Web App开发,就如字面意思一样是基于Web网页的一类App开发方式。这种开发方式无论是对Android开
发还是iOS开发都非常简单,开发成本低更新快,可以跨多个平台运行。当让这种开发方式缺点也有很多列如相比
Native App开发方式功能有限,如果App数据过多手机容易卡死,页面访问速度慢等等。
最后一种开发方式是Hybrid App开发,这种开发方式最大的优点是兼顾其他两大开发方式的优点。目前这种
App 开发方式在市场上十分受欢迎。其开发成本介于Hybrid App开发与Native App开发之间,开发周期也介于两大
App的编程之间,这也它受欢迎的重要原因。在综合考虑开发成本、开发周期以及所要实现的功能等各个方面,最后
从上面三种App编程的方式选择了Hybrid App开发。
2.3设计难点
1.DHT11程序的编写:DHT11程序的编写对时序要求极高,所以要完成程序的编写必须处理好单片机STC89C52的时序。
如果处理不好时序问题,单片机就无法读取DHT11发送的数据。
2.手机APP的编写:对于手机App编程,我在大学四年基本没有研究过在这一领域可以说是一片空白,所有关于App编
程的工作都要从零开始。对于App编程的方式、App编程软件的选择、App的页面设计、联网、云平台传输数据再到
App打包,这些每一个过程都需要查找大量的资料来研究。
3.联网通信:在本科学习期间,学习过移动通信,但当时是疫情期间,但大部分都是在家完成学习,在这方面的实践
次数少,要完成ESP8266与手机App联网通信有一定难度
3系统硬件设计
3.1主控电路
本设计是以STC89C52为核心的嵌入式开发,其自带的功能和资源足够完成本次设计[13]。选用该单片机作为主
控电路芯片,不仅仅是因为其是在本科阶段接触最多的单片机对其的使用方法了解很多,而且其性价比高。
STC89C52主要功能和资源
512字节数据存储器 8K字节的Flash程序存储器
5K字节的EE-PROM 3个16位可编程定时/计数器中断
32个双向I/O口
可编程UART串行通道复位电路
表3.1 STC89C52主要功能和资源
下面对本次设计主要用到的单片机功能和资源的介绍: (1)时钟电路
时序电路由两个30pF的陶瓷电容(直插式)分别和一个12MHz的晶振并联组成,电容在这里作用是帮助晶振起
振,滤波,维持振荡信号的稳定。晶振的作用是为单片机系统提供基准时钟信号,是单片机工作的基础。如果缺少
或使用晶振与所使用的程序不协调,都会导致单片机无法正常完成工作。STC89C52内部时钟电路如图3.1所示。
图3.1 STC89C52内部时钟电路
(2)复位电路
复位电路的作用就行电脑的重启一样,这样设计是当遭受意外单片机死机或程序跑飞的情况下,当按下复位按
键单片机所有电路会回到起始状态下,重新运行一次所有的初始化程序,再进入while循环当中。
(3)中断概述
中断目的是提高单片机时间利用率。中断就是在程序执行的过程中,突然有其他的程序要运行,就中断原先正在执
行的程序,去执行另一个程序当程序完成后,再返回原先的程序继续运行。我们可以看这种工作方式是在同时运行
两个程序,大大提高了程序对时间的利用率。图3.3为中断响应和处理过程。
(4)串行通信UART
串行通信是将数据的每一位在同一个数据线上按照顺序逐位发送或接受。同并行通信相比较,串口通信具有占
用串口资源少、传输距离长、并且由于串行通信的通信时钟频率容易提高,所以抗干扰能力强。串行通信也有缺
点,在传输速度上,串口通信要比并行通信慢得多。同时,还有注意串口通信的两个设备的波特率要一致,否则无
法实现信息的发送与接收[14]。单片机之间的串口通信方式如图3.4。
图3.4 单片机之间的串口通信方式
3.2温湿度检测电路
DHT11是一款符合本设计要求的传感器,可以同时达成对周围温度与湿度的测量任务。传感器能同时完成这样测
量的原因是其内部包含一个电阻式温湿元件与一个NTC测温元件,并可以将测量好的数据通过单线双向的传输方式传
给单片机中[15]。温湿度检测电路由DHT11与一个上拉电阻组成如图3.5。
该温湿度传感器的数据采集过程:在采集数据之前,传感器的2号引脚在空闲状态下为高电平,在要开始采集数
据时单片机引脚输出低电平,将传感器的2号引脚拉低至少18us,再将低电平拉高时长在20-40us之间,经过传感器低电平相应信号80us后,完成这一系列的操纵后传感器开始工作,传感器会将温湿度的数据以40bit数据的形式传输到
单片机做进一步处理。
该传感器传输数据比较特殊,传输数据“0”与“1”的判断是在50us的低电平之后的,高电平时长来判断的,
高电平时长在26-28us判断为“0”,高电平时长在70us判断为“1”。
表3.2 引脚说明
编号 符号 类型 引脚说明
1 VDD 电源 正电源,3V-5.5V
2 Dout 输出 单总线,数据输入/输出引脚
3 NC 空脚 空脚,扩展未用
4 GND 地 电源地
3.3 MQ-2烟雾检测电路
该部分设计使用MQ-2型电阻式半导体传感器采集烟雾信号,该传感器使用在清洁空气中导电率较低的二氧化锡
制成。当检测空气中的烟雾浓度上升时,传感器的导电率也随之增强,再经放大器将电压放大。MQ-2气敏传感器要
先加热才能使用,所以MQ-2气敏传感器需要通电60-90s,传感器才能进入稳定的工作状态。这也解释了传感器会发
热,是正常反应。该传感器有6只针状管脚,其中2个用于加热传感器,其他4个用于信号取出
该部分包括蜂鸣器报警和LED报警,蜂鸣器报警原理图如图3.7,由蜂鸣器、PNP三极管、1K欧姆电阻组成,这样
设计的理由是蜂鸣器使用时电流很大,容易损坏单片机,所以需要使用三极管驱动。单片机控制三极管基极来控制
蜂鸣器的运作。
3.5 LCD1602液晶显示电路
LCD1602液晶显示器,字如其名它是由可以显示两行,每行16个字符的液晶组成。LCD1602自带自带数字和英文
大小写字符以及一些特殊符号的字符库,如果想要LCD1602显示汉字可以在LCD1602片内的CCRAM空间里存放8个6X8点
阵的汉字自建库。可以通过调节3号引脚的电压来调节液晶中的显示黑点与不显示黑点的对比度,使显示器显示字符
更加清晰,此处通过调整电位器的分压值来调节3号引脚的电压,如图3.8所示 。可以通过调整4、5、6引脚对于的
RS、R/W、E的高低电平,来向LCD1602发送四个操作时序,包括读状态、写指令、读数据、写数据等指令[16]。
表3.3 1602液晶引脚功能
引脚编号 符号 引脚说明 引脚编号 符号 引脚说明
1 VSS 电源地 9 D2 Data I/O
2 VDD 电源负极 10 D3 Data I/O
3 VL 液晶显示偏压信号 11 D4 Data I/O
4 RS 数据/命令选择端 12 D5 Data I/O
5 R/W 读写选择端 13 D6 Data I/O
6 E 使能信号 14 D7 Data I/O
7 D0 Data I/O 15 BLA 背光源正极
8 D1 Data I/O 16 BLK 背光源负极
图3.9 LCD1602内部RAM结构图
LCD1602的第一行的地址是由0X00H到0X27H,第二行的地址是由0X40H到0X67H,LCD1602内部RAM结构如图4.9所
示。而液晶显示器每个行只有16个字符也就是只需要16个地址就可以对应16个字符,多出来的一部分是为了显示移
动字幕设置的。
3.6 红外出入检测
电路
图3.10 传感器内部原理图
E18-D80NK-N光电开关传感器由一个红外发射器和一个红外接收器构成,如图3.10所示。该传感器是数字传感器
输出状态只有高电平和低电平这两种状态。当接通电源在传感器前没有障碍物传感器输出高电平,背部的小红灯处
于灭的状态,只有当检测到前方由障碍物时,传感器才输出低电平,背部的小红灯处于亮的状态。而且E18-D80NKN 可以通过背部的电位器来调节检测障碍的距离,将障碍物放至需要的距离,调节电位器,当红灯亮起的时候停止
调节,这样E18-D80NK-N就调节好了,需要注意的是E18-D80NK-N的有效调节距离在3到80CM之间。
表3.4 光电开关传感器的电气特性
名称 参数
工作电压 5VDC
工作电流范围 10—15mA
驱动电流 100mA
感应距离 3—80cm
室内总闸及照明设施控制电路
继电器原理:通过给电磁线圈加电,使电磁线圈产生磁力吸引继电器中的衔铁,工作电路闭合。当电磁线圈断电,线圈中的衔铁会在弹簧的作用下,使工作电路断开。
继电器作用:有隔离作用,隔离强电与弱电避免强电进入弱电系统破坏弱电电路与元器件、可以使用低电压控
制高电压,提高电路的安全性和稳定性同时减少能量的损耗。
将LED灯的阳极接到继电器上,阴极接到单片机上,点亮LED灯的条件是接高电平的继电器闭合,单片机串口输
出低电平,就可以点亮LED灯,该控制LED亮灭的命令是由手机App发出。继电器作为教室总闸,只有当继电器处于导
通的情况下,才能可以控制教室的灯。
3.8ESP8266 模 块 ESP8266芯片是由乐鑫公司研发的一款串口转无线模芯片[17]。
ESP8266有两种固件:一种是ESP8266出厂时内部自带AT固件,用户可以通过串口使用AT指令来控制ESP8266的工作。
另一种是Node-mcu固件,这种固件最大的魅力就在于你可以自己定制模块,包括UART、I2C、PWM 、GPIO和ADC 等模
块,但由于ESP8266的FLASH内存空间不足情况,所以要根据需求来配置模块的固件。而且使用Node-mcu固件可以使
用Arduino来编程程序,相比与AT固件,这种编辑方式更加方便,清晰且自由度更高。
4系统软件设计
4.1软件介绍
本设计所使用的软件有用于编程的软件HBuilder X、Keil uVision5、Arduino,用于调试的软件Configure
Virtual Serial Port Driver、Proteus 8 Professional、Stc-isp-15xx-v6.88,用于电路设计的软件Altium
Designer,用于固件烧录的软件ESP8266FIasher。下面对主要软件进行介绍。
4.1.1HBuilder X
HBuilder X是由DCloud(数字天堂)开发的一款轻如编辑器、强如IDE的合体版本。开发App利用HTML5+技术,
结合mui+nativejs可以打包出Android和iOS的App。HBuilder X操作界面如
图4.1。使用HBuilderX开发APP不仅仅可
以在手机上同步测试,还可以使用内置模拟器这大大加快开发者的调试进程。我在查找各种App编程软件后发现这些
软件大多都是国外开发所以基本没有工具对中国小程序开发优化,但HBuilder X不仅支持uni-app或小程序、快应用
等项目的开发,而且对国人程序开发十分友好。同时HBuilder X有着极强的扩展性,支持java插件、nodejs插件,
并兼容了很多vscode的插件及代码块。所以我选择HBuilder X为我的APP编程软件[18]。
图4.1 HBuilder X操作界面
4.1.2Keil uVision5
Keil5 MDK是时代
发展的产物,它是由Keil从一代逐渐发展而来,中间被英国的ARM公司收购,随后在ARM公司的大力发展下最终形成
了现在的这个版本。Keil5和以前广泛使用的Keil4相比有了质的飞跃,Keil4是早期为了51单片机的开发使用服务的,所以它并不能支持其他系列的单片机开发。但是随着时代的发展,51系列单片机已经渐渐跟不上发展需求,所
以Keil4也渐渐不在适应市场。这时Keil5出现了,它可以完美的兼容Keil4,还可以满足更多的芯片开发需求,而且
它对初学者十分友好,操作简单,且性能上限很高的软件开发系统。自带Debug可以对已经编辑好的程序进行简单的
运行模拟,也可以通过烧录器来调试已经烧录好代码的单片机。在性能方面,Keil5的SWD下载速度也是KEIL4的5倍
左右。总而言之,不管对于是有着多年开发经验的嵌入式工程师还是对于刚刚入门的新手, Keil5 都是开发者的不
二之选。
4.1.3Stc-isp-15xx-v6.88
STC-ISP是一款针对STC系列单片机编程烧录软件,能将Keil5编译好的HEX文件烧录进单片机中。这款烧录软件
不仅仅能为单片机烧录程序,还可以辅助单片机程序开发,为程序开发提供波特率计算器、定时器计算器、软件延
时计算器等等,提高程序开发进程,使用简便。STC-ISP上面还配有串口助手可以用来监控单片机的串口数据传出以
及往单片机内发送命令。STC-ISP操作界面如图4.4。
4.1.4Stc-isp-15xx-v6.88
STC-ISP是一款针对STC系列单片机编程烧录软件,能将Keil5编译好的HEX文件烧录进单片机中。这款烧录软件
不仅仅能为单片机烧录程序,还可以辅助单片机程序开发,为程序开发提供波特率计算器、定时器计算器、软件延
时计算器等等,提高程序开发进程,使用简便。STC-ISP上面还配有串口助手可以用来监控单片机的串口数据传出以
及往单片机内发送命令。STC-ISP操作界面如图4.4。
4.1.5ESP8266FIasher ESP8266FIasher是ESP8266的固件烧录工具。ESP8266FIasher操作界面如图4.5。在硬件设备
中,固件就像是硬件设备的基础建设,这些基础建设就是固件之中包含的各种模块,之后再烧录的程序就是利用这些模块来实现各种
功能,因此固件也就决定了硬件设备的功能。所以我们可以通过烧入固件来提高其使用灵活性。根据烧录不同的固
件的ESP8266可以选用Arduino、ESPPlorer等不同的开发软件。本设计使用的NodeMCU固件,使用Arduino开发后期程
序。
图4.5 ESP8266FIasher操作界面
4.2程序简介
4.2.1STC89C52程序简介
该设计部分主要完成对周围数据的的采集实现手机下达的命令,并将采集处理好的数据通过串行通信传输进
ESP8266的数据存储空间。
程序完成对DHT11初始化、LCD1602液晶显示器初始化、串行通信波特率初始化,将DHT11模块、MQ-2模块以及光
电开关采集数据打包成以“S”为开头以“T”为结尾的字符串,经串行通信传输的ESP8266数据存储空间。通过串口
中断读取手机App发送到ESP8266的命令并执行。
4.2.2ESP8266程序简介
该部分程序设计可以看作中转站,将STC89C52采集的数据通过网络传输至手机App中,同时将手机下达的命
令, 传输给STC89C52中。
首先,ESP8266通过链接WIFI无线网,登入贝壳物联。然后,利用以下程序当接收到STC89C52发送的数据,将数
据以“S”为开头以“T”为结尾,对从STC89C52接收到的数据进行裁剪,再对裁剪好的字符串进行二次裁剪。
if (Serial.available()) if(Serial.find(“S”)) {
serialData = Serial.readStringUntil(‘T’); serialData1 = serialData.substring(0,2); serialData2 =
serialData.substring(2,4); serialData3 = serialData.substring(4,5); sayTophon(“D20750”,serialData1,"
0"); sayTophon(“D20750”,serialData2,“1”);
sayTophon(“D20750”,serialData3,“4”); if(serialData2>=“20”) sayTophon(“D20750”,serialData2,“5”);
}
最后,将二次裁剪的字符串,通过贝壳物联平台送到手机App中。
4.2.3手机APP程序简介
该设计部分将STC89C52数据显示到手机屏幕中,并可以通过App之中的按键控制STC89C52。
该部分App设计将分成两个界面,一个界面是显示温度和湿度并且包含对室内与总闸的控制,另一个界面是显示
人员出入时间情况。通过界面按键,将命令传输至贝壳物联平台上,再传输到ESP8266上。
首先对所有功能进行初始化,接着进入while死循环。在死循环中,读取烟雾传感器、温湿度值以及光电开关的数
据,判断所采集的温湿度是否在阈值范围内,如果超出触发警报。并将采集的数据送到LCD1602显示。当接受到手机
App发送来的指令,触发串口中断,判断App所要执行的指令,单片机执行。
图4. 系统程序流程图
4.4贝壳物联云平台
贝壳物联云平台支持第三方智能平台如百度的DuerOS、天猫的Aligenie、小米的XiaoAi等也支持用户的浏览
器、微信小程序、公众号、自行开发APP与网络,还有可以连接入网的设备。
该设计使用贝壳物联提供的云平台完成手机APP与ESP8266的数据传输。贝壳物联平台采用两种通信协议:一种
是TCP协议,另一种为UDP协议。这两种协议之间信息可以互通。
贝壳物联平台的取用户资源、向设备发送指令、上传图片等功能都是基于TCP协议之上,使用TCP或websocket建
立长连接与设备进行通讯[20]。且贝壳物联平台可以免费使用,只需要注册用户,就可以在贝壳物联操作界面,就
可以为设备申请ID与APIKEY,这是本设计联网传输数据的重中之重,这两个数据就想是为设备申请的身份证一样,
每一个设备只有一个。这就确保两个设备可以准确的找到对方并传输数据。而且贝壳物联提供的操作界面还可以监
控所以设备的在线情况、在线时间,对设备发送指令以及监控设备之间的对话。
本设计主要使用以下的两个指令完成用户与设备、设备与设备、用户与用户间沟通指令数据: 1.{“M”:"
checkin",“ID”:“xx1”,“K”:“xx2”}
该指令作用是设备登录,这里的"ID"后面的xx1是本设备的ID,"ID"后面的xx2是本设备的APIKEY,这就是设备
的身份证。
2.{“M”:“say”,“ID”:“xx1”,“C”:“xx2”,“SIGN”:“xx3”}
该指令作用是实现用户与设备、设备与设备、用户与用户间沟通指令数据,
这里的"ID"后面的xx1是本设备数据传输目标设备的ID,"C"后面的"xx2"是传输的内容,"SIGN"后面的"xx3"是
自定义字符串,可以用于签名标签。
附录
附录C 程序代码
手机App代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum- scale=1,
user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet"/>
<script type="text/javascript" charset="utf-8"> mui.init();
</script>
</head>
<body>
<div id="home" class="mui-control-content mui-active">
<header class="mui-bar mui-bar-nav">
<h1 class="mui-title">我的App</h1>
</header><br>
<nav class="mui-bar mui-bar-tab">
<a class="mui-tab-item mui-active" href="#tabbar">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">开关控制</span>
</a>
<a class="mui-tab-item" href="#tabbar-with-chat">
<span class="mui-icon mui-icon-person"></span>
<span class="mui-tab-label">人员出入记录</span>
</a>
</nav>
22
<!-- 第一界面 -->
<br>
<br>
<div id="tabbar" class="mui-control-content mui-active">
<button id="btn6" type="button">打开总闸</button>
<button id="btn5" type="button">关闭总闸</button>
<br><br>
<button id="btn4" type="button">打开灯1</button>
<button id="btn3" type="button">关闭灯1</button>
<br><br>
<button id="btn2" type="button">打开灯2</button>
<button id="btn1" type="button">关闭灯2</button>
<br><br>
<u>连接状态:</u>
<span id="sp1">连接中. </span>
<br>
<u>温度:</u><span id="sp2" style ="font-size:20px"></span>
<br>
<u>湿度:</u><span id="sp3"style ="font-size:20px"></span>
<br>
<span id="jname"></span>
<br>
</div>
<!-- //人员出入界面 -->
<div id="tabbar-with-chat" class="mui-control-content">
<span id="bl">当前时间:</span><div id="times"></div>
<div class="mui-scroll">
<ul class="mui-table-view mui-table-view-chevron"></ul>
</div>
</div>
<!-- 人员出入记录函数 -->
<script type="text/javascript"> function getD1(){
var date=new Date();
var d1=date.toLocaleString();
var div1=document.getElementById("times"); div1.innerHTML=d1;
return d1;
}
setInterval("getD1();",1000);
function addData(tmp) {
var table = document.body.querySelector('.mui-table-view');
var cells = document.body.querySelectorAll('.mui-table-view-cell'); for(var i = cells.length, len =
i + 1; i < len; i++) {
var li = document.createElement('li'); li.className = 'mui-table-view-cell'; if(tmp=='i')
li.innerHTML = '<a class="mui-navigate-right"> 入'+getD1()+'</a>'; if(tmp=='o')
li.innerHTML = '<a class="mui-navigate-right"> 出'+getD1()+'</a>'; table.insertBefore(li, table.
firstChild);
}
23
}
</script>
<!-- 连接与传输数据与开关控制函数 -->
<script type="text/javascript">
var ws = new WebSocket("ws://www.bigiot.net:8383"); var lb = document.getElementById("sp1");
ws.onopen = function()
{lb.innerText="链接成功"
};
ws.onmessage = function (evt)
{var received_msg = evt.data;
var obj = JSON.parse(received_msg); if(obj.M=="WELCOME TO BIGIOT")
{ ws.send('{"M":"checkin","ID":"20750","K":"54561815c"}');
}
if(obj.M=="ping")
{ ws.send('{"M":"beat"}');
}
if(obj.M=="say")
{ if(obj.ID=="D20759")
{if(obj.SIGN=="0")
{
document.getElementById("sp2").innerHTML=obj.C; document.getElementById("sp2").value;
} if(obj.SIGN=="1")
{
document.getElementById("sp3").innerHTML=obj.C; document.getElementById("sp3").value;
} if(obj.SIGN=="4")
{if(obj.C=='i')
addData('i');
if(obj.C=='o')
addData('o');
} if(obj.SIGN=="5")
{mui.alert("火灾警报");
}
}
}
};
});
});
});
});
});
});
document.getElementById("btn1").addEventListener("click",function(){ ws.send('{"M":"say","ID":"
D20759","C":"play1","SIGN":"xx3"}');
document.getElementById("btn2").addEventListener("click",function(){ ws.send('{"M":"say","ID":"
D20759","C":"stop1","SIGN":"xx3"}');
document.getElementById("btn3").addEventListener("click",function(){ ws.send('{"M":"say","ID":"
D20759","C":"play2","SIGN":"xx3"}');
24
document.getElementById("btn4").addEventListener("click",function(){ ws.send('{"M":"say","ID":"
D20759","C":"stop2","SIGN":"xx3"}');
document.getElementById("btn5").addEventListener("click",function(){ ws.send('{"M":"say","ID":"
D20759","C":"play3","SIGN":"xx3"}');
document.getElementById("btn6").addEventListener("click",function(){ ws.send('{"M":"say","ID":"
D20759","C":"stop3","SIGN":"xx3"}');
</script>
</body>
</html>
ESP8266程序:
#include <ESP8266WiFi.h> #include <aJSON.h>
String DEVICEID="20759";//贝壳物联里智能设备的ID String APIKEY="095df5458";//贝壳物联里智能设备的
密码const char* ssid="vivoX21A";//WiFi名称
const char* password="12345678";//WiFi密码unsigned long lastCheckInTime=0;//记录上次报到时间
const unsigned long postingInterval=40000;//每隔40秒向服务器报到一次const unsigned long
Interval=400;//每隔40秒向服务器报到一次
const char* host="www.bigiot.net";//贝壳网站const int httpPort=8181;//TCP端口
WiFiClient client;//用户void setup()
{ Serial.begin(2400);// 波 特 率 为 2400 WiFi.begin(ssid,password);// 连 接 WiFi while(WiFi.status()!
= WL_CONNECTED)//等待WiFi连接成功
{delay(500);
Serial.print(".");} Serial.println();
}
String serialData; String serialData1; String serialData2; String serialData3; void loop()
{ if(!client.connected())//检测是否成功链接服务器
{if(!client.connect(host, httpPort))//连接服务器
{Serial.println("connection failed"); delay(5000);
return;}
}
if(millis()-lastCheckInTime>postingInterval||lastCheckInTime==0)//设备运行时间-记录上次报到时间
>40秒或记录上次报到时间为0
{
checkIn();//ESP8266链接到贝壳物联函数
}
if(Serial.available())//当串口接收到信息后if(Serial.find("S")) {
serialData = Serial.readStringUntil('T'); serialData1 = serialData.substring(0,2); serialData2 =
serialData.substring(2,4); serialData3 = serialData.substring(4,5); sayTophon("D20750",serialData1,"
0"); sayTophon("D20750",serialData2,"1"); sayTophon("D20750",serialData3,"4"); if(serialData2>="20")
sayTophon("D20750",serialData2,"5");
}
if (client.available())
{String inputString=client.readStringUntil('\n');//读取数据直到指定字符并保存为字符串{"M":"
say","ID":"xx1","C":"xx2","SIGN":"xx3"}\n
inputString.trim();//删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等
//Serial.println(inputString);//输出inputString int len=inputString.length()+1;//inputString+1
if(inputString.startsWith("{") && inputString.endsWith("}"))//inputString以‘{’开始以‘}’结束
{ char jsonString[len]; inputString.toCharArray(jsonString,len);//将字符串改成字符数组
25
aJsonObject *msg = aJson.parse(jsonString);//从字符串中解析出JSON对象
processMessage(msg); aJson.deleteItem(msg); // 删除meg中的数值
}
}
}
void processMessage(aJsonObject *msg)
{ aJsonObject* method=aJson.getObjectItem(msg,"M"); aJsonObject* content=aJson.getObjectItem
(msg,"C"); aJsonObject* client_id=aJson.getObjectItem(msg,"ID");
if(!method) return;
String M=method->valuestring; if(M=="say")
{ String C=content->valuestring; String F_C_ID=client_id->valuestring;
digitalWrite(LED_BUILTIN,LOW);//接收到指令就闪一下LED delay(50);
digitalWrite(LED_BUILTIN,HIGH); if(C=="stop1")//接收到的是停止指令
{ sayToClient(F_C_ID,"LED All off!"); //发送给贝壳物联LED All off!
Serial.print(0); } if(C=="play1")//接收到的不是停止指令
{ sayToClient(F_C_ID,"LED All on!"); //发送给贝壳物联LED All off!
Serial.print(1);} if(C=="stop2")//接收到的是停止指令
{ sayToClient(F_C_ID,"LED All off!"); //发送给贝壳物联LED All off!
Serial.print(2); } if(C=="play2")//接收到的不是停止指令
{ sayToClient(F_C_ID,"LED All on!"); //发送给贝壳物联LED All off!
Serial.print(3); } if(C=="stop3")//接收到的是停止指令
{ sayToClient(F_C_ID,"LED All off!"); //发送给贝壳物联LED All off!
Serial.print(4); } if(C=="play3")//接收到的不是停止指令
{ sayToClient(F_C_ID,"LED All on!"); //发送给贝壳物联LED All off!
Serial.print(5); }
}
}
void checkIn()//ESP8266链接到贝壳物联函数
{String msg="{\"M\":\"checkin\",\"ID\":\"" + DEVICEID + "\",\"K\":\"" + APIKEY + "\"}\n"; client.
print(msg);
lastCheckInTime=millis();//板子运行时间
}
void sayToClient(String client_id, String content)//
{String msg="{\"M\":\"say\",\"ID\":\"" + client_id + "\",\"C\":\"" + content + "\"}\n"; client.
print(msg);
lastCheckInTime=millis();//板子运行时间
}
void sayTophon(String client_id, String content,String sing)//
{String msg="{\"M\":\"say\",\"ID\":\"" + client_id + "\",\"C\":\"" + content + "\",\"SIGN\":\""
+ sing + "\"}\n"; client.print(msg);
lastCheckInTime=millis();//板子运行时间
}
STC89C52程序:
#include<main.h>
uchar code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9'};
uchar send[8] = {'S','1','2','3','4','5','T'};
uint innum=0; uint outnum=0; uchar inflag=0; uchar outflag=0; bit flag;
26
bit busy;
bit flag_inter; uchar GetC;
void buzz_contral()
{if(button1==0)
{ Relay=1; buzz=0; LED3=1;
}
}
void uart_contral()
{ if(flag)
{if(GetC=='0')
{LED1=0;
}
else if(GetC=='1')
{LED1=1;
}
else if(GetC=='2')
{ LED2=0;
}
else if(GetC=='3')
{LED2=1;
}
else if(GetC=='4')
{Relay=0;
}
else if(GetC=='5')
{ Relay=1;
}
flag=0;
}
}
void count(uint num,uchar x1,uchar x2,uchar x3,uchar y1)
{ uchar disbuff[4]={ 0,0,0,0}; disbuff[0]=num/100; disbuff[1]=num%100/10;
disbuff[2]=num%1000%100%10; DisplayOneChar(x1, y1, ASCII[disbuff[0]]); DisplayOneChar(x2, y1,
ASCII[disbuff[1]]); DisplayOneChar(x3, y1, ASCII[disbuff[2]]);
}
void inoutnum()
{ if(RAD1==0)
inflag=1; if(RAD2==0&&inflag==1)
{inflag=0; while(!RAD1); innum++; count(innum,3,4,5,1);
send[5]='i'; uart_send_str(send); send[5]='1';
}
if(RAD2==0)
outflag=1; if(RAD1==0&&outflag==1)
{outflag=0; while(!RAD2); outnum++;
count(outnum,12,13,14,1); send[5]='o'; uart_send_str(send); send[5]='1';
}
}
27
void main()
{ ALL_Init(); while(1)
{ uart_contral(); DHT11_receive(); inoutnum(); buzz_contral();
}
}
void uart_interrupt(void) interrupt 4
{
if(RI)
{ RI = 0; GetC=SBUF;
flag=1;
}
if(TI)
{ TI = 0;
busy=0;
}
}
#ifndef MAIN_H_ #define MAIN_H_ #include<reg51.h> #include<LCD1602.h> #include<DELAY.h>
#include<DHT11.h> #include<intrins.h> #include<intrins.h> #include<UART.h> #include<INIT.h> sbit
RAD1= P3^2; sbit RAD2= P3^3; sbit LED1 = P1^0; sbit LED2 = P1^1; sbit Relay = P1^2; sbit LED3 =
P1^3; sbit button = P3^5; sbit button1 = P3^4; sbit buzz= P3^7; #ifndef uchar
#define uchar unsigned char #endif
#ifndef uint
#define uint unsigned int #endif
#endif #include"main.h"
voidRead_Busy()//忙检测函数,判断bit7是0,允许执行;1禁止
{unsigned char sta; // LCD1602_DB = 0xff; LCD1602_RS = 0;
LCD1602_RW = 1;
do
{
LCD1602_EN = 1; sta = LCD1602_DB;
LCD1602_EN = 0; //使能,用完就拉低,释放总线
}while(sta & 0x80);
}
void Lcd1602_Write_Cmd(unsigned char cmd) //写命令
{
Read_Busy(); LCD1602_RS = 0;
LCD1602_RW = 0; LCD1602_DB = cmd; LCD1602_EN = 1;
LCD1602_EN = 0;
}
void Lcd1602_Write_Data(unsigned char dat) //写数据
{
Read_Busy(); LCD1602_RS = 1;
LCD1602_RW = 0; LCD1602_DB = dat; LCD1602_EN = 1;
LCD1602_EN = 0;
}
void LcdSetCursor(unsigned char x,unsigned char y) //坐标显示
{
28
unsigned char addr; if(y == 0)
addr = 0x00 + x; else
addr = 0x40 + x;
Lcd1602_Write_Cmd(addr|0x80);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40; X |= 0x80; //算出指令码
Lcd1602_Write_Cmd(X); //发命令字Lcd1602_Write_Data(DData); //发数据
}
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) //显示字符串
{
LcdSetCursor(x,y); //当前字符的坐标while(*str != '\0')
{ Lcd1602_Write_Data(*str++);
}
}
void InitLcd1602() //1602初始化
{ Lcd1602_Write_Cmd(0x38); //打开,5*8,8位数据Lcd1602_Write_Cmd(0x0c); Lcd1602_Write_Cmd(0x06);
Lcd1602_Write_Cmd(0x01); //清屏
}
#ifndef LCD_H_ #define LCD_H_ #include<reg51.h> #ifndef uchar
#define uchar unsigned char #endif
#ifndef uint
#define uint unsigned int #endif
#define LCD1602_DB P0 sbit LCD1602_RS = P2^6; sbit LCD1602_RW = P2^5; sbit LCD1602_EN = P2^7;
void Lcd1602_Delay1ms(uint c); void Read_Busy();
void Lcd1602_Write_Cmd(unsigned char cmd); void Lcd1602_Write_Data(unsigned char dat);
void LcdSetCursor(unsigned char x,unsigned char y);
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str); void InitLcd1602();
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); #endif
#include"main.h"
void DHT11_delay_us(uchar n)
{ while(--n);
}
void DHT11_delay_ms(uint z)
{ uint i,j; for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void us_delay(uchar t)
{while(t--);
}
void Delay500ms()//@12.000MHz
{unsigned char i, j, k;
_nop_();
29
_nop_(); i = 23;
j = 205;
k = 120;
do
{ do
{while (--k);
} while (--j);
} while (--i);
}
#ifndef DELAY_H_ #define DELAY_H_ #include<main.h>
void DHT11_delay_us(uchar n); void DHT11_delay_ms(uint z); void us_delay(uchar t);
void Delay500ms(); #endif #include<main.h> extern uchar send[7];
sbit Data=P3^6; //定义数据线void DHT11_start()
{
Data=1; DHT11_delay_us(2); Data=0;
DHT11_delay_ms(30); //延时18ms以上Data=1;
DHT11_delay_us(30);
}
uchar DHT11_rec_byte() //接收一个字节
{
uchar i,dat=0;
for(i=0;i<8;i++) //从高到低依次接收8位数据
{
while(!Data); 等待50us低电平过去DHT11_delay_us(8);//延时60us,如果还为高则数据为1,否则为0
dat<<=1; //移位使正确接收8位数据,数据为0时直接移位if(Data==1) //数据为1时,使dat加1来接收数据1
dat+=1;
while(Data); //等待数据线拉低
}
return dat;
}
void DHT11_receive() //接收40位的数据
{uchar rec_dat[9]; //用于显示的接收数据数组uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
DHT11_start();
if(Data==0)
{
while(Data==0); //等待拉高DHT11_delay_us(40); //拉高后延时80us R_H=DHT11_rec_byte(); //接收湿度高
八位R_L=DHT11_rec_byte(); //接收湿度低八位T_H=DHT11_rec_byte(); //接收温度高八位T_L=DHT11_rec_byte();
//接收温度低八位revise=DHT11_rec_byte(); //接收校正位
DHT11_delay_us(25); //结束if((R_H+R_L+T_H+T_L)==revise) //校正
{RH=R_H; RL=R_L; TH=T_H; TL=T_L;
} if(R_H>=80)
{buzz=0; Relay=0; LED3=0;
}
rec_dat[0]='0'+(RH/10);
rec_dat[1]='0'+(RH%10);
rec_dat[2]='R';
rec_dat[3]='H';
30
rec_dat[4]='0'+(TH/10);
rec_dat[5]='0'+(TH%10);
rec_dat[6]='C'; DisplayOneChar(4,0,rec_dat[0]); DisplayOneChar(5,0,rec_dat[1]); DisplayOneChar
(6,0,rec_dat[2]); DisplayOneChar(7,0,rec_dat[3]); DisplayOneChar(12,0,rec_dat[4]); DisplayOneChar
(13,0,rec_dat[5]); DisplayOneChar(14,0,rec_dat[6]); send[1]=rec_dat[4]; send[2]=rec_dat[5]; send[3]
=rec_dat[0]; send[4]=rec_dat[1]; uart_send_str(send);
}
}
#ifndef DHT11_H_ #define DHT11_H_ #include<main.h> void DHT11_start();
uchar DHT11_rec_byte(); void DHT11_receive(); #endif
#include "main.h" extern bit busy; void init_uart(void)
{
SCON=0X50;//设置为工作方式1 TMOD=0X20;//设置计数器工作方式2
//PCON=0X80;//波特率加倍
TH1=0XF3;//计数器初始值设置,注意波特率是4800的TL1=0XF3;
ES=1;// 打 开 接 收 中 断 EA=1;// 打 开 总 中 断 TR1=1;//打开计数器 //打开串口中断
}
// 发送一个字节数据
void uart_send_byte(unsigned char dat)
{
while(busy); busy=1; SBUF=dat;
}
// 发送字符串
void uart_send_str(unsigned char *s)
{
while(*s != '\0')// '\0':字符串结束标志
{uart_send_byte(*s++);// 发送1个字节数据,1个字符占8位,1字节
}
us_delay(5); uart_send_byte('\r'); //回车us_delay(5); uart_send_byte('\n');
}
#ifndef UART_H_ #define UART_H_ #include<main.h>
void uart_send_byte(unsigned char dat); void uart_send_str(unsigned char *s); void init_uart
(void);
#endif #include<main.h> void displayInit()
{
LcdShowStr(0,0,"Welcome to use"); LcdShowStr(0,1," My APP "); Delay500ms(); Lcd1602_Write_Cmd(0x01);
LcdShowStr(0,0,"him: tmp:");
LcdShowStr(0,1,"in: out:");
}
void ALL_Init()
{ buzz=1; Relay=1; LED1=1; LED2=1; LED3=1;
InitLcd1602(); displayInit(); init_uart();
}
#ifndef INIT_H_ #define INIT_H_ #include<main.h> void displayInit(); void ALL_Init(); #endif
5.系统调试
调试首先检测硬件电路设计是否正确、是否能达到预期效果以及电路是否有可以优化空间等;其次在焊接好硬
件电路后,与PCB图对比检测是否有与电路设计一致、是否有虚焊点;最后,在完成每个功能模块的测试,没问题后
将所有模块功能一起运行,测试是程序否有冲突。
1、调试过程
使用Keil5编程的程序编译结果,如下图
图5.1 程序编译结果
使用Stc-isp-15xx-v6.88将HEX文件烧录入单片机STC89C52中,结果如下。
图5.2 STC-SIP烧录成功界面
将使用Arduino编辑的ESP8266程序编译并上传到ESP8266芯片中,结果如下图。
图5.3 ESP8266编译成功界面
将HBuilder X编辑程序打包成App,结果如下图。
图5.4 App 打 包 App界面包括总闸灯1灯2的开关、温湿度显示以及App与贝壳物联云平台连接情况,App界面如图
5.5所示。
图5.5 App界面1
图5.6是App第二个界面,
主要功能是显示教室出入情况。
图5.6 App界面2
当教室温度超过预设值或触发烟雾传感器时,手机App界面会出现“火灾报警”的警示界面,如图7.7所示。同时,
硬件电路上的蜂鸣器发出报警声。
图5.7 火灾警报
2、 在调试过程中遇到的问题及解决方法
(1)电路焊接完成后,无法运行程序,在进行各种检测后,判断是排母接触不良,由于设备受限,最后选择重
新焊接。
(2)在测试液晶显示器LCD1602的程序时,没有正常显示,原以为是程序错误,在开发板上测试后,确定是液
晶显示器LCD1602模块损害,初步判断损害是由于元器件老化,更换了液晶显示器LCD1602模块问题解决。
(3)在焊接电路时发现单片机STC89C52的工作电压与ESP8266工作电压不匹配,最终使用ESP8266开发板自带的
降压模块来给ESP8266供电。
(4)开发板的晶振是12MHz,而设计的电路上的晶振是11.0592MHz,因为DTH11温湿度检测模块与波特率设计对
晶振有严格要求有严苛的要求,所以在开发板上正常运行的程序,不能在设计的电路板上正常工作,最后更换了晶
振。
6.总结与展望
6.1总结
毕业设计是对我们大学四年生涯的最后一个环节,是大学生活的句号,是对我们所学基础知识和专业知识的掌
握力度的考核。
从选题开始,查找资料、制定方案、选取材料、设计电路、软件编程、调试,最后完成设计。我的毕业设计可
以说是我将本科所学知识进行了汇总,同时还学习本科期间不曾学到的课外知识。在本次设计中。在本次设计最难
的就是联网传输数据与控制指令,这个过程设计到手机App、ESP8266、单片机STC89C52以及贝壳物联平台,这个过
程是整个设计的支架,而难就难在这个支架要自己一点点摸索搭建。ESP8266与STC89C52之间的串口通信是本科使用
最多通信方式。手机App与ESP8266之间的互联网对话,则需要额外学习。这也是我问题频发的地方,相比于串口通
信,互联网对话就要复杂的多,但在查阅资料、咨询老师、同学网友的帮助下,最终将各种问题解决,完成对支架
的构建。同时也明白了错误的原因,掌握了技术,提高了自己的认知。搭建好支架后,就开始往支架上放各种功
能,这里主要是使用了本科期间所学的单片机原理与接口技术,不仅仅检验自己大学的学习成功,也加深自己对这
方面的印象。
通过本次设计发现自己的能力还远远不足,也意识到自己掌握的知识太少,要学的东西还有很多,大学的知识
对于我们步入社会只是一块敲门砖,在这个知识技术不停迭代更新的时代,不学习新知识便意味着落后,只有跟上
时代的步伐不断学习扩充自己的知识库,才能提高自己的价值。这是自己可以在今后社会立足的资本。
6.2展望
本设计为基于STC89C52的教室安全监控系统设计主要体现在“监”和“控”上,在此基础之上,对其功能进行
扩展和完善。
(1)可以通过红外发射器来控制教室空调,因为每一个品牌空调的红外频段不一样如果想要控制全部或大部分空
调会占用大量的STC89C52内存空间甚至于超过STC89C52的内存空间,导致整个系统反应迟钝或无法完成程序的编
译。但可以将这些不同品牌空调的红外频段,存放在手机App中,利用手机内存来存放这些信息,但工作量过于
巨大,考虑到设计时间的问题暂时,未将该功能纳入本设计中。不仅仅是红外发射器来控制教室空调的功能,还可
以实现教室用水量监控、指纹锁等功能,均可加入本设计。
(2)本设计只针对单一教室,可以将每一个教室的信息进行汇总,传入教室管理的电脑中,可以更加直接的监管
每一个教室的安全。
(3)App界面优化,一个好的App界面可以瞬间抓住人的注意。而本次设计一是自己的对于这方面的知识不足,二
是时间紧张。
附录
原理图