基于ESP32的智能家居管理系统的设计与实现
ESP32的智能家居管理系统访问链接: https://www.cnblogs.com/easyidea/p/13101165.html
一、需求分析
1.1硬件需求
1.1.1 蓝牙收发数据
1.1.2 网络收发数据
1.1.3 传感器检测
1.1.4 开关控制
1.1.5 PWM电机控制
1.1.6 舵机控制
1.1.7 OLED显示
1.1.8 自动控制
1.2 微信小程序需求分析
1.2.1 用户登录
1.2.2 设备管理
1.2.3 数据修改
1.2.4 创建定时任务
1.2.5 控制ESP32
1.2.6 接受ESP32的数据
二、总体设计
2.1 总体设计要求
2.1.1 简单
2.1.2 智能
2.1.3 跨平台
2.1.4 模块化
2.1.5 可拓展
2.1.6 自适应
2.2 数据交互
2.2.1数据传输
2.2.2数据约定
2.2.3 数据安全
2.3 硬件总体设计
2.3.1 引脚分配
2.3.2硬件总体结构设计
2.3.3传感器
2.3.4 控制器
2.4 软件总体设计
2.4.1服务器搭建
2.4.2微信小程序设计
2.5 数据库总体设计
三、数据交互详细设计
3.1数据约定
3.2数据包装
3.3 AES加密解密
3.4 BLE发送数据处理
四、硬件详细设计与实现
4.1 传感器
4.1.1温度湿度数据采集
4.1.2气体数据采集
4.1.3预留传感器
4.2 控制器
4.2.1电风扇控制
4.2.2舵机控制
4.2.3 OLED显示器
4.2.4 蜂鸣器
4.2.5 红外活体检测
4.3 蓝牙收发数据
4.4 Wi-Fi联网
4.5 MQTT协议收发数据
4.6 ESP32多任务配置
4.6.1中断
4.6.2 多任务
4.6.3 多核心
五、软件设计与实现
5.1 数据库详细设计与实现
5.1.1数据库实体设计
5.1.2数据库ER图
5.1.3数据库表设计
5.2 服务器搭建与实现设计与实现
5.2.1 EMQ X服务器软件搭建
5.2.2 Nginx服务器搭建
5.3 微信小程序设计与实现
5.3.1功能设计与实现
5.3.2界面设计与实现
六、成品展示
6.1 ESP32设备硬件展示
6.2 微信小程序展示
基于ESP32的智能家居管理系统的设计与实现
摘要 :ESP32智能家居管理系统由硬件和软件组成。能够实现数据采集、红外遥控、蓝牙控制、远程控制,还能对采集的数据进行处理发出警报。
硬件部分包括乐鑫信息科技股份有限公司推出ESP32主控芯片,传感器和控制器。传感器主要有MQ2可燃气体检测传感器、MQ135烟雾检测传感器、DHT11温度湿度检测传感器、土壤湿度检测传感器、雨水检测传感器等组成。控制器有红外发光二极管、电动风扇、电动舵机、发光二极管、蜂鸣器等组成。
软件部分包括微信小程序、Tomcat服务器、Nginx服务器、EMQ服务器、MySql数据。微信小程序上位机可以发出指令、接收数据、显示数据、修改数据、保存数据,用户通过微信小程序控制ESP32。Tomcat服务器用来处理小程序的业务操作。Nginx用来代理网络请求。EMQ服务器用来接收转发MQTT协议数据。Mysql用来储存ESP32硬件设备的信息和用户信息数据。
需求分析
1.1硬件需求
1.1.1 蓝牙收发数据
ESP32将传感器检测的数据通过蓝牙发送出去,还可以接受蓝牙的数据通过数据提取做出相应动作。
1.1.2 网络收发数据
ESP32将检测的数据通过网络发送出去,还可以接受网络的数据通过数据提取做出相应动作。
1.1.3 传感器检测
(1)温度湿度检测
ESP32每隔一段时间通过传感器检测空气中的温度和湿度。检测的数据会通过蓝牙或者网络发送到微信小程序。
(2)气体检测
ESP32每隔一段时间通过传感器检测气体中的可燃气体或是烟雾。检测的数据会通过蓝牙或者网络发送到微信小程序。
(3)雨水检测
ESP32每隔一段时间通过传感器检测是不是有雨水。检测的数据会通过蓝牙或者网络发送到微信小程序。
(4)土壤湿度检测
ESP32 每隔一段时间通过传感器检测土壤的湿度数据。检测的数据会通过蓝牙或者网络发送到微信小程序。
(5)活体检测
ESP32通过传感器检测周围是不是有活物,如果有活物做出相应的动作。例如用户夜晚起来上厕所,那么活体检测器检测的哦有活物时,ESP32把灯打开。
1.1.4 开关控制
开关控制是ESP32的核心功能,因为智能家居管理系统的核心就是通过开关来控制,那么开关能控制的开关越多越好。
1.1.5 PWM电机控制
PWM是一种脉冲信号,可以通过不同的空占比来控制电机的速度。
1.1.6 舵机控制
舵机可以用来控制门锁,舵机根据接受到的pwm脉冲信号旋转到不同的角度。
1.1.7 OLED显示
OLED的作用就是把传感器检测的数据显示出来。
1.1.8 自动控制
自动控制是当某个传感器的的值超出正常范围的时候发出预警,比如说当检测的可燃气体浓度过高时触发蜂鸣器发出警吧。或是当检测到烟雾是触发电风扇转动。
1.2 微信小程序需求分析
1.2.1 用户登录
由于用户已经登录微信那么可以直接获取用户的登录状态。如果需要用户的头像或昵称等信息那么就需要用户授权才能获取。
1.2.2 设备管理
(1)激活设备
一个用户可以拥有多台ESP32设备,一台ESP32设备也可以被多人拥有,用户一旦激活ESP32设备那么它就能获取设备传感器数据,控制设备。设备第一次被激活那么该用户拥有对设备的最高控制权限,该用户为root(管理员)用户。如果设备再次被激活那么激活者为person(普通用户)。
(2)切换设备
由于用户可以拥有多台设备那么用户可以切换不同的设备使用。
(3)设备授权
设备的root用户可以对person用户进行权限分配,root用户也可以给自己分配权限。person用户被权限分配之后将不再接受权限之外的数据。
1.2.3 数据修改
数据修改包括传感器名称,开关名称修改,电机名称修改,红外指令修改,触发条件修改。在数据库中每个开关、传感器、电机、遥控器都有自己的ID、名称、值。触发条件保存在ESP32设备中通过指令可以修改触发的条件。
1.2.4 创建定时任务
定时任务就是可以给一个控制指设置时间,到时自动执行。
1.2.5 控制ESP32
小程序通过蓝牙发送指令给ESP32设备,这些指令在小程序端和硬件端相互约定,通过约定的指令来实现控制的功能。
1.2.6 接受ESP32的数据
小程序能够通过蓝牙的方式接受ESP32设备发出的数据,也可以通过通过MQTT协议订阅主题的方式接受ESP32设备发送到EMQ X服务器的数据。
总体设计
2.1 总体设计要求
2.1.1 简单
(1)开发方式简单
开发方式简单主要是为了方便后期维护,硬件程序采用Arduino开发大大简化了开发步骤,使开发人员主要考虑业务逻辑。微信小程序开发也极大的节省了开发流程。
(2)软件使用简单
用户通过微信小程序控制ESP32设备,微信小程序打开即用,无需安装任何软件。
2.1.2 智能
ESP32可以根据用户设定的条件来自动做出处理,当传感器的值大于或小于某个值的时候会自动发出警报,用户还可以设置定时任务,如同闹钟一样定时执行该任务。
2.1.3 跨平台
现在的移动端主要是IOS系统和Android系统,用户的手机无论是IOS系统和Android系统都可以对硬件进行控制。
2.1.4 模块化
模块化是指硬件的各个功能区进行模块化设计,如果某个模块坏了不影响其它模块的正常使用,模块可容易的拆卸和更换。
2.1.5 可拓展
可拓展主要是针对硬件的设计如控制器的数量,和模块化。硬件预留可拓展的接口如果后续需要对硬件进行升级可以很方便的拓展。如果某个模块坏了可以随时维护,更换。
2.1.6 自适应
微信小程序开发需要在不同尺寸的屏幕上都能正常显示数据,不会出现超出屏幕显示或是显示紊乱等情况。
2.2 数据交互
2.2.1数据传输
数据传输:
图2-1 数据传输流程图
微信小程序和ESP32之间采用蓝牙进行数据直接交互,实现蓝牙控制、蓝牙获取数据。ESP32也可以把数据发送到EMQ X服务器上,由EMQ X服务器转发给微信小程序实现远程数据获取,微信小程序吧数据发送到EMQ X服务器,由EMQ X服务器转发给ESP32实现远程控制。
2.2.2数据约定
数据约定就是约定一段数据的某些字段代表什么意思,在进行数据传输的过程中需要约定数据格式,最方便的一种方式就是json格式但是由于ESP32处理json格式耗费时间占用内存,更重要的原因是在蓝牙传输数据过程中由于微信小程序只支持蓝牙低能耗(Bluetooth Low Energy简称BLE)每次传输最多20个字符,而且微信小程序不支持修改最大传输单元(Maximum Transmission Unit,MTU)那么传输的数据长度越短越好。因此需要自己定义数据传输的格式。
设备ID | 时间位 | 操作码 | 地址码 | 数据码 | 合计 | 预留 | 总记 |
32 | 13 | 6 | 1 | 16 | 68 | 32 | 100 |
图2-2 数据约定图
设备ID:ESP32设备拥有唯一的设备ID,发送指令的时候需要携带设备ID,当ESP32设备接受数据时会验证ID是否相同,如果相同则有权操控设备。如果不同则不做任何处理。
时间位:时间位是格林威治标准时间1970 年1 月1 日的00:00:00.000到现在的毫秒数,加上时间指令的意义在于每次发送的指令不重复,过时作废。
操作码:操作码表示ESP32设备进行什么操作,例如“opensw”的意义是打开开关,那么ESP32会去判断要执行什么操作。
地址码:地址码用来表示对应操作码的编号,例如“2”代表第二个。
数据码:数据码用来存放要操作的数值,例如:设置电机转速为1024。
为什么数据格式是这样的?请看下面的数据安全分析。
2.2.3 数据安全
(1)数据验证
验证数据是保证数据安全的一种方式,那么需要在数据中加入验证的字段,最好的方式就是每次传输数据过程中加入设备的ID,因为设备ID是唯一的,当ESP32接受到数据的时候提取数据中的设备ID字段与内存中自带的字段进行比较,如果相同那么就验证通过,如果不同验证不通过。
(2)数据唯一
经过数据验证还是达不到数据安全的地步,需要对数据进行进一步的处理。数据的唯一性是保证数据安全的另一种方式,举个例子:当微信小程序发送控制信息给ESP32设备的时候,如关闭开关指令数据,因为每次的指令都是相同的,如果下次再发送该的指令数据依然可以操作设备,那么这样的指令如果被窃取,将很容易的控制ESP32设备。解决办法就是把指令变得唯一,那么只需要在发送的指令当中添加一部分的随机字符就可以把指令变得唯一。
(2)数据作废
经过数据验证,数据唯一处理之后数据还是指令还是不安全!因为指令即使是唯一的那么如果该指令被窃取再次发出该指令依然可以控制ESP32 设备。要解决这个问题需要让已经发出的指令作废,下次不能再使用。解决办法就是给指令加上时间,每次ESP32接受数据之后验证接收的时间与上次接收的时间那个大,如果新接收的时间在上次指令之前那么指令作废,反之验证通过。
(3)数据加密
在经过经过数据验证,数据唯一处理、数据作废之后可以说数据已经很安全了,但是还不是绝对的安全,因为BLE在传输的过程中可能被截取,通过对截取的数据进行分析,很容易得出规律,那么之前的操作都有白费了,数据安全的终极大发就是数据加密,加密后的数据即使被截取也很难被破解,即使被破解由于数据的唯一性,也不能再被使用了,解决办法就是将数据,经过以上处理之后再进行AES算法加密。待ESP32接收到数据之后通过AES算法解密。这样处理之后的控制指令数据将是极其安全的。
2.3 硬件总体设计
2.3.1 引脚分配
在进行设计之前需要对ESP32的引脚进行分配。
图2-3 ESP32 MCU引脚约定图
通过上图可以发现本系统设计过程中几乎耗尽了ESP32的所有可用引脚。
2.3.2硬件总体结构设计
硬件主要由控制器和传感器构成。
图2-4 硬件模块构成
2.3.3传感器
传感器由,温度湿度传感器、气体检测传感器、雨水检测传感器、土壤湿度检测和预留接口传感器组成。
2.3.4 控制器
控制器由,电风扇、舵机、红外发射和预留电机接口器组成。
2.4 软件总体设计
2.4.1服务器搭建
项目中微信小程序的后台服务器是Tomcat,用来处理微信小程序的业务,EMQ X服务器用来处理微信小程序与ESP32设备之间的数据交互。因为小程序只支持HTTPS协议那么就需要Nginx来转发请求。
2.4.2微信小程序设计
(1)模块划分
小程序界面可以划分为三个模块,第一个模块是蓝牙,包括蓝牙搜索界面及蓝牙连接界面。第二个模块为设备模块,包括传感器数据展示界面,开关控制界面,电机控制界面,遥控控制界面等。
2.5 数据库总体设计
由于用户通过微信小程序控制ESP32设备那么,设备上所有的传感器及控制器都名称都应该保存到数据库中。需要建立用户表,用户登录信息表,设备表,传感器表,控制器表。
数据交互详细设计
3.1数据约定
当小程序发送数据给ESP32设备的时候需要进行数据约定,当ESP32接收到数据之后根据约定的数据进行相应的操作如表5-1数据约定表。
表3-1 数据约定表
功能 |
约定 |
示例 |
解释 |
设置Wi-Fi名称 |
stWiFi |
stWiFin12345678 |
Wi-Fi名称为12345678 |
设置Wi-Fi密码 |
stWiFi |
stWiFip12345678 |
Wi-Fi密码为12345678 |
设置开关状态 |
switch |
switch1true |
开关1开 |
设置开关状态 |
switch |
switch1false |
开关1关 |
设置电动机 |
pwm_EM |
pwm_EM11020 |
电机1最大功率 |
设置电动机 |
pwm_EM |
pwm_EM10000 |
电机1关闭 |
设置转向舵机 |
pwm_SE |
pwm_SE1t |
舵机转向 |
设置转向舵机 |
pwm_SE |
pwm_SE1f |
舵机复位 |
传感器触发蜂鸣器 |
TG_S_B |
TG_S_B1>500 |
传感器1的值大于500时触发 蜂鸣器 |
活体检测触发开关 |
TG_I_S |
TG_I_S@t1t |
活体检测开(有活体)触发开关1打开 |
传感器触发PWM电机 |
TG_S_E |
TG_S_E1>400B100 |
传感器的值大于400时,电机的值为100 |
微信小程序和ESP32设备通过上表发送数据,处理数据。
3.2数据包装
真实的数据在传输过程中不安全需要进行包装之后才能处理之后才能发送。
(1)加入设备ID
操作:加入设备ID,例如原数据为“switch1true”(开关1开)那么加入设备ID之后变成“a411a6ec84de4d00aae73677dadb2901switch1true”,设备ID长度是32字节,加入设备ID之后在接收段先验证ID,相同才执行操作,反之则不执行操作。
意义:因为蓝牙是开放连接的那么任何人都可以连接ESP32设备,对其发送数据,如果不加设备ID进行验证,通过遍历的方式将很快破解ESP32控制指令,者对ESP32设备来说是极不安全的。
(2)加入时间信息
原因:因为在BLE4.2之前发送信息可能被窃取,那么设备ID被窃取后数据会变得不安全。
操作:加入时间信息。加入时间信息之后每次ESP32接收信息之后先验证当前数据的时间与上一条指令的时间进行比较看是否过期,如果过期则不执行该指令,反之执行相应操作。
意义:加入之间参数之后每一条指令都是唯一的,而且发送之后就不能再次使用,必须下次的时间大于本次时间才行。
3.3 AES加密解密
AES的算法本身是跨平台的,只不过以下这些要素决定了跨平台不是那么简单:
加密模式: ECB,CBC,CFB,OFB,CTR,XTS...
密钥长度: 128, 256
iv向量: 需要与密钥同时设置
padding: NoPadding,ZeroPadding,PKCS5Padding,ISO10126Padding,ANSI X.923,SSL3Padding...
密钥: 用于加解密的key
只有当这5个要素都完全一致时,AES的加密和解密才可以在任何地方通用,实现跨平台.一般的编程语言会支持ECB,CBC,CFB这几种常见的加密模式,以及128的密钥长度,但在padding的处理方式上,各个语言的区别就太大了,而且这个padding与加密模式也存在紧密的关联.
AES的一些加密模式需要原文的bytes数是16的倍数,以下是信息表:
图3-2 填充模式比较图
解决办法:
在微信小程序引入Crypto-JS库中加密时采用默认填充。在ESP32中采用AESLib库,使用相同的iv和key即可实现正常的加密解密。
3.4 BLE发送数据处理
图3-3 BLE发送数据流程图
由于BLE最多只能发送20个字节,而常用的解决办法就是修改MTU(最大传输单元),但是微信信息不支持修改MTU那么只能采用分包的方式发送数据。为了保证数据完整性将数据包分为18个字节,每次最多发送18个字节多次发送即可完成数据发送。但是接收段如何处理数据呢?由于接收端不知道接受的数据有多大,更不知道什么时候结束。解决办法就是加入起始字符和结束字符,但是由于可能发送的数据中包含起始字符和结束字符,从而导致接收处理的数据不完整,那么就要选用特殊字符来作为起始字符和结束字符。在ASCII表中0-32号字符为不可见字符,也就是说ASCII表中0-32号字符不回出现在发送的数据中,那么正好可以用来作为起始字符、结束字符。
硬件详细设计与实现
4.1 传感器
4.1.1温度湿度数据采集
(1)传感器选择
温度湿度数据采用DHT11温度湿度传感器传感器。DHT11 数字温湿度 传感器是一款含有已校准数字信号输出的温湿度复合传感器 。它应用专用的数字模块采集技术和温湿度传感技术 ,确保产品具有极 高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比 极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP 内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单 线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20 米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为4针单排引脚封装。连接方便,特殊封装形式可根据用户需求而提供。
图4-1 DHT11传感器图
(2)引脚说明
引脚说明:
Pin |
名称 |
注释 |
1 |
VDD |
供电 3-5.5V |
2 |
DATA |
串行数据,单总线 |
3 |
NC |
空脚,悬空 |
4 |
GND |
姐弟,杰电源负级 |
表4-2 DHT11引脚说明表
(3)传感数据获取
在ArduinoIDE中搜索DHT sensor library库下载安装,打开示例代码即可即可实现温度湿度数据采集。实现代码请参考附录硬件代码。
4.1.2气体数据采集
(1)传感器选择
气体传感器采用MQ135气体传感器,MQ135气体传感器对氨气、硫化物、苯系蒸汽的灵敏度高,对烟雾和其它有害气体的监测也很理想。这种传感器可检测多种有害气体,是一款适合多种应用的低成本传感器。
图4-3 MQ135传感器图
(2)引脚说明
图4-4 MQ135传感器说明图
(3)数据获取
由于MQ135输入的是模拟信号直接调用Arduino函数analogRead(Pin);即可得到数据。实现代码请参考附录硬件代码。
4.1.3预留传感器
由于土壤湿度传感器、雨水传感器、热敏传感器、光敏传感器等都是传感器加电阻转电压模块组成,那么可以把电阻转电压模块提取出来,留出一些接口插槽来给传感器使用,当要使用什么传感器的时候就插入对于的传感器。
图4-5 传感器图
使用ESP32读取模拟值意味着您可以测量0 V至3.3 V之间的变化电压电平。
然后,将测得的电压分配给一个介于0和4095之间的值,其中0 V对应于0,而3.3 V对应于4095。0V和3.3 V之间的任何电压都将被赋予介于两者之间的对应值。
为了实现自动切换传感器省去手动切换,需要一个可以通过电路信号来选择通道的器件。通过查询相关资料找到CD74HC4051一个高速CMOS 8通道模拟多路复用器和多路信号分离器。通过输入信号可以切换通道使其导通。
图4-6 74H4051引脚图
表4-7 74H4051引脚说明表
表4-874H4051真值表
通过对74HC4050器件的引脚说明和真值表分析之需要3个选择输入端即可控制8个通道的任意一个通道的导通,那么采用ESP32设备的G5,G18,G19引脚来连通74HC4051器件的9,10,11选择引脚。再采用ESP32的SVP引脚来连通74HC4051器件的公共引脚Z(3)即可实现一个电阻转电压模块与多个传感器相连接的目的。由于74HC4051器件有8个独立输入输出端,目前之有雨水传感器,土壤湿度传感器连接,剩下的6个独立输入输出端将作为预留传感器的接口。实现代码请参考附录硬件代码。
4.2 控制器
通过PWM来控制电机的优势在于可以通过改变PWM来控制电机的转速,常见的电机有电风扇,电马达等。
4.2.1电风扇控制
(1)电风扇选择
本设计中采用5V的电风扇来模拟家居环境中的大功率电风扇、油烟机风扇。
选择MG995R 金属齿轮舵机,来模拟自动开门、关门、开窗等。
图4-10 电风扇图
图4-11 电风扇功率对照图
(2)电风扇控制
通过电风扇的的功率对照表可以发送即是是5V的电风扇,ESP32依然无法直接驱动它转动。那么就需要一个转换模块,接收PWM信号转换为输出对应的电流。这里我采用pwm直流驱动模块。
图4-12 pwm直流驱动模块
pwm直流驱动模块由双路H桥电机驱动,可以同时驱动两路直流电机或者1个4线两相式步进电机,模块供电电压2V-10V,信号端输入电压1.8-7V,单路工作电流1.5A,峰值电流可达2.5A,低待机电流(小于0.1uA),内置防共态导通电路,输入端悬空时,电机不会误动作,内置带迟滞效应的过热保护电路(TSD),无需担心电机堵转。
表4-13 pwm直流驱动模块逻辑真值表
通过ESP32设备pwm直流驱动模块去控制电机这样就实现了所需的功能。
图4-14 电机控制原理
这样使用了模块化的思想,如果电机控制模块或电机坏了那么更换坏掉的模块就行了,而不会影响ESP32设备的正常运行。实现代码请参考附录硬件代码。
4.2.2舵机控制
舵机是一一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时, 通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
(1)舵机选择
在本设计中选用MG996R型号的舵机。
图4-15 MG996R舵机图
(2)引脚说明
黄色导线接5V电压,棕色导线接地(GND),黄色导线(信号)。
(3)舵机控制
单片机系统实现对舵机输出转角的控制,必须首先完成两个任务:首先是产生基本的PWN周期信号,本设计是产生20ms的周期信号;其次是脉宽的调整,即单片机模拟PWM信号的输出,并且调整占空比。
在Arduino中引入“ESP32_ISR_Servo”库该库提供舵机相关的控制方法。
4.2.3 OLED显示器
(1)OLED 显示器选择
在本设计中使用的使一款0.96寸蓝色IIC驱动屏,其内置驱动芯片为SSD1306。
图4-16 0.96寸OLED显示屏图
这里0.96寸OLED分辨率是128*64;即OLED显示是128行*64列,但是由于OLED不能一次控制一个点阵,只能控制8个点阵;而且是垂直方向扫描控制;
(2)引脚说明:
OLED的GND引脚接ESP32设备的GND引脚。
OLED的VCC引脚接ESP32设备的GND引脚。
OLED的SCL引脚接ESP32设备的CLK时钟引脚。
OLED的SDA引脚接ESP32设备的MOSI数据引脚。
(3)显示汉字
我们使用的OLED屏是由方形的发光点阵列组成的,分辨率为128x64。汉字最小显示像素为16x16,要显示需要的字符只需对应点亮像素区域中对应的发光点即可。
图4-17 子模提取图
为了方便实现需要用到字模提取软件(PCtoLCD)。
①Windows系统下双击启动软件,点击「模式」,选择「字符模式」,通常默认就是字符模式。
图4-18 PCtoLCD软件图
② 点击「选项」进行字模配置。通常字模配置要根据程序驱动方式来选择,本篇中我们选择阴码、逐行式、顺向,其他选项如下图所示。
图4-19 PCtoLCD软件设置图
③ 输入汉字。点击生成字模或者保存字模,就会得到对应的点阵数据。
图4-20 PCtoLCD子模提取图
④把得到的子模保存到代码中即可显示该汉字。
4.2.4 蜂鸣器
蜂鸣器是一种电子发声元器件,可以发出"beep"的声音。采用直流电压供电,广泛应用于计算机、电磁炉、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。
(1)蜂鸣器选择
发蜂鸣器主要分为一下两种:
有源蜂鸣器: 内部带有震荡源,只要一通电就会发出固定频率的声音。
无源蜂鸣器:内部不带震荡源,需要使用2KHz到5KHz的脉冲信号驱动发声,声音频率可变。
本设计中采用无源蜂鸣器。
图4-21 蜂鸣器
(2)蜂鸣器发声
要使蜂鸣器发声就产生发送脉冲信号,在Arduino中针对ESP32的脉冲信号函数有:
ledcSetup(channel, freq, resolution);//用来产生特定频率的脉冲信号
ledcAttachPin(12, channel);//用来将信号与引脚进行绑定。
ledcWriteTone(channel, 2000);//重新设置频率。
4.2.5 红外活体检测
(1)传感器选择
活体检测采用HC--SR501人体感应模块,HC--SR501是基于红外线技术的自动控制模块,可靠性强,灵敏度高,超低电压工作模式,被广泛应用于各类自动感应控制的电器设备当中。
图4-22 HC--SR501人体感应模块
(2)传感器特点
全自动感应:当活物进入其感应范围则输入高电平,离开后感应范围则自动关闭高电平,输出低电平。模块预留有位置,可设置光敏控制,白天或光线强时不感应。功耗低工作电压范围宽。
图4-23 探测范围图
(4)检测活体
通过图的说明可以知道HC--SR501检测到有活体的时候输出高电平,那么通过Arduino的digitalRead(); 函数即可读取该数据,如果为高电平证明有活物,如果为电平则没有活物。实现代码请参考附录硬件代码。
4.3 蓝牙收发数据
(1)ESP32 BLE配置
蓝牙是一种短距离通信技术,蓝牙系统分为两种不同的技术:经典蓝牙(Classic Bluetooth)和蓝牙低功耗(Bluetooth Low Energy)。由于微信小程序只支持BLE开发那么需要配置ESP32设备的BLE。
(2)收发数据
由于已经约定了数据传输的格式那么,处理后的数据进行发送即可,对接收的数据进行,相应的逆操作即可。在ArduinoIDE中的实例库中提供了8个示例如果下图所示,实现代码请参考附录硬件代码。
图4-25 Arduino IDE图
4.4 Wi-Fi联网
在Arduino已经封装了ESP32设备的Wi-Fi库,配置ESP32设备接入互联网需要让ESP32设备知道接入Wi-Fi热点的名称和密码。
在ArduinoIDE示例代码中提供了Wi-Fi热点及密码的配置方法,通过调用<WiFi.h>库来实现对热点及密码的配置。实现代码请参考附录硬件代码。
4.5 MQTT协议收发数据
ESP32设备通过mqtt发布主题,接收消息需要“PubSubClient”库。MQTT的原理是传统的客户端-服务器模型。在此模型中,有一个MQTT服务器(也称为代理)和许多MQTT客户端。MQTT客户端始终保持与MQTT服务器的连接。MQTT服务器(代理)的作用是过滤消息并将其转发到已订阅的MQTT客户端。客户端之间的通信基于发布/订阅/主题模式。实现代码请参考附录硬件代码。
4.6 ESP32多任务配置
ESP32设备需要进行传感器数据采集,OLED显示,蜂鸣器发声,电机转动,网络数据收发,蓝牙数据收发等功能。这些任务很多是实时的如OLED显示,蜂鸣器发声,那么当ESP32设备在做着一件任务的时候需要做另一件任务怎么办呢?在ESP32设备中可以通过配置中断来解决这个问题。
4.6.1中断
(1)中断是什么?
中断就是当CPU正在处理任务A时,发生了任务B请求CPU去处理,CUP暂停任务A去处理任务B,处理完成之后任务B之后再返回任务A执行任务。
①硬件中断
硬件中断由物理信号生成,可以来自微控制器本身(例如,作为总线控制器的一部分),也可以来自配置为中断的外部GPIO。例如某个引脚的电平输入信号由低电平转为高电平时触发中断。外部中断是可以屏蔽的中断,也就是说,利用中断控制器可以屏蔽这些外部设备问 的中断请求。
②软件中断
软件中断由微控制器执行的指令生成。例如数据自增,当数据自增大于某个数的时候触发中断。内部中断是不可屏蔽的中断。
(2)中断与多任务
通过中断就能实现多个任务的切换,由于切换时间短,几乎可以忽略不计,这样多个任务一起执行,达到并发执行的目的。
4.6.2 多任务
解决的办法就是配置多任务,每个任务执行来回切换实现多个任务的同时执行。Arduino 提供的“Thread”库可以来实现多任务并发执行。
4.6.3 多核心
ESP32拥有两个核心,那么可以做到在两个核心上运行的任务同时执行。通过任务来回切换可以实现多个任务的并发执行,那么在核心分配上就可以根据任务的属性把任务放在不同的核心上执行。根据数据传输来说可以把设备分为蓝牙传输,和网络传输。根据任务执行时长来说可以把任务分为瞬时任务和持续任务。瞬时任务包括开关任务,传感器数据采集任务,检测Wi-Fi或MQTT服务器连接任务以及OLED任务。持续任务包括舵机任务,蓝牙接收数据任务。根据任务执行频率可以分为低平任务,和高频任务。低平任务包括数据采集任务,OLED显示任务,检测Wi-Fi或MQTT服务器连接任务。高频任务包括Wi-Fi或蓝牙接收数据任务,触发器任务。
软件设计与实现
5.1 数据库详细设计与实现
5.1.1数据库实体设计
(1)用户实体
用户实体对应每个一个授权登录的用户,保存着用户的唯一标识OpenID。
图5-1 用户实体图
(2)设备实体
设备实体主要存放ESP32设备的ID字段和名称主题等信息。
图5-2 设备实体图
(3)用户与设备关系实体
设备与用户之间是多对多的关系,那么用户与设备关系实体就是用来保存着这多对多的关系的。
图5-3 关系实体图
(4)登录状态实体
当用户登录小程序之后需要有一个表来保存用户当前的的sessionkey,微信小程序每次和服务器进行数据交互的时候都要将sessionkey携带上。通过sessionkey就能知道用户是谁了。
图5-4 登录状态图
(5)开关实体表
开关属于设备,但是ESP32设备拥有很多开关和其它控制器,如果把开关数据保存和设备数据存放在一起不利于维护和升级,那么把开关数据单独提取出来对其进行增删改查都将变得容易。
图5-5 开关实体图
(6)任务实体,任务并非时间存在的事物,它是由用户设置之后产生的,任务依托于设备,任务会随着时间的流逝而被服务器删除。
图5-6 任务实体图
(7)传感器实体,传感器是指将传感电阻数据映射为电压的传感器,传感器种类很多。但是无论什么传感器都有固定的ID编号。
图5-7 传感器实体图
(8)红外遥控实体,遥控器实体主要保存遥控编码。
图5-7 红外遥控实体图
(9)电机实体,电机包括电风扇,舵机等。
图5-8 电机实体图
5.1.2数据库ER图
(1)数据库ER简略图。
图5-9 ER简略图
(2)数据库ER图。
图5-9 ER完整图
5.1.3数据库表设计
根据数据库实体图可以构建数据库表。
(1)用户表
表5-10 用户表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
user_id |
int |
11 |
非空约束、自增 |
主键 |
用户ID |
open_id |
varchar |
64 |
小程序OpenID |
||
user_bickname |
varchar |
60 |
用户昵称 |
||
user_head_url |
varchar |
2048 |
用户头像地址 |
||
creat_time |
timestamp |
默认为插入时间 |
创建时间 |
(2)设备表
表5-11 设备表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
device_id |
int |
11 |
非空约束、自增 |
主键 |
设备ID |
device_name |
varchar |
100 |
默认为“ESP32” |
加密后的sessionkey |
|
device_macid |
varchar |
64 |
非空约束 |
外键依赖与设备表ID |
用户正在使用的设备ID |
create_time |
timestamp |
默认为插入时间 |
创建时间 |
(3)用户登录状态sessionkey表
表5-12 登录状态表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
sessionkey_user |
int |
11 |
非空约束 |
主键外键依赖与用户表的用户ID |
用户ID |
session_key |
varchar |
64 |
唯一性约束 |
加密后的sessionkey |
|
user_current_device |
int |
11 |
外键依赖与设备表ID |
用户正在使用的设备ID |
|
update_time |
timestamp |
默认为更新时间 |
更新时间 |
(4)用户与设备关系表
表5-13 关系表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
device_and_user_id |
int |
11 |
非空约束、自增 |
主键 |
关系ID |
device_id |
int |
11 |
非空约束 |
外键依赖与设备表的设备ID |
设备ID |
user_id |
int |
11 |
非空约束 |
外键依赖与用户表的用户ID |
用户ID |
user_key |
varchar |
20 |
默认为“p0000000000” |
用户对设备的控制权限 |
|
activation_time |
timestamp |
插入时的时间 |
激活时间 |
(5)开关数据表
表5-14 开关数据表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
switch_id |
int |
11 |
非空约束、自增 |
主键 |
开关ID |
device_id |
int |
11 |
非空约束 |
外键依赖与设备表的设备ID |
开关所属设备 |
switch_name |
int |
30 |
开关名称 |
||
switch_state |
tinyint |
大小 (0-255) |
开关状态 |
(6)传感器表
表5-15 传感器数据表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
sensor_id |
int |
11 |
非空约束、自增 |
主键 |
传感器ID |
sensor_device |
int |
11 |
非空约束 |
外键依赖与设备表的设备ID |
传感器所属设备 |
sensor_name |
varchar |
30 |
传感器名称 |
||
sensor_value |
smallint |
大小 (-32768到32767) |
传感器的值 |
(7)温度湿度传感器数据表
表5-16 温度数据表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
ht_id |
int |
11 |
非空约束、自增 |
主键 |
传感器ID |
ht_device |
int |
11 |
非空约束 |
外键依赖与设备表的设备ID |
传感器所属设备 |
ht_name |
varchar |
30 |
温度湿度传感器名称 |
||
temperature_value |
smallint |
大小 (-32768到32767) |
默认为0 |
温度湿度传感器的值 |
|
humidity_value |
smallint |
大小 (-32768到32767) |
默认为0 |
(8)遥控表
表5-17 遥控数据表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
ir_id |
int |
11 |
非空约束、自增 |
主键 |
遥控器ID |
ir_device |
int |
11 |
非空约束 |
外键依赖与设备表的设备ID |
遥控器所属设备 |
ir_name |
varchar |
30 |
遥控器名称 |
||
ir_code |
varchar |
30 |
遥控器编码的值 |
(9)pwm电机表
表5-18 pwm电机数据表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
slider_id |
int |
11 |
非空约束、自增 |
主键 |
电机ID |
slider_device |
int |
11 |
非空约束 |
外键依赖与设备表的设备ID |
电机所属设备 |
slider_name |
varchar |
30 |
电机名称 |
||
slider_value |
smallint |
大小 (-32768到32767) |
默认为0 |
电机的值 |
(10)任务表
表5-19 任务数据表
字段名 |
数据类型 |
长度 |
约束 |
主键/外键 |
中文名称 |
task_id |
int |
11 |
非空约束、自增 |
主键 |
任务ID |
device_id |
int |
11 |
非空约束 |
外键依赖与设备表的设备ID |
任务属设备 |
task_name |
varchar |
30 |
默认为“任务” |
任务名称 |
|
run_time |
timestamp |
非空约束 |
任务执行时间 |
||
mqtt_topic |
varchar |
50 |
非空约束 |
任务通过MQTT发布的主题 |
|
mqtt_message |
varchar |
1024 |
非空约束 |
任务通过MQTT发布的内容 |
5.2 服务器搭建与实现设计与实现
5.2.1 EMQ X服务器软件搭建
本设计中采用阿里云的Ubuntu16.4系统来搭建EMQ X服务器软件。因为EMQ服务器软件是开源免费的代码被托管到GitHub上,那么可以很容易的下载安装。搭建过程很简单这里主要简述搭建的步骤:第一步将EMQ X的安装包下载解压到阿里云的服务器上,第二步安装EMQ X服务器软件,第三步启动EMQ X配置端口及密码等。
5.2.2 Nginx服务器搭建
在本设计中Nginx服务器只有用来代理https网络请求,因为小程序只允许访问https请求。因为Nginx服务器软件是开源的,那么可以很容易的搭建及部署。下面简述搭建流程:第一步下载解压Nginx到服务器上,第二步安装Nginx,第三步修改配置文件。
5.3 微信小程序设计与实现
5.3.1功能设计与实现
(1)登录小程序
用户打开小程序即可进入小程序的主页面,并且可以查看小程序显示的默认数据,而不能对小程序进行任何操作,如果用户需要对ESP32设备进行操控那么久需要激活设备,在激活设备之前需要用户授权头像昵称等信息,虽然说用户一旦进入小程序就可以通过用户携带的code信息获取用户的OpenID(微信小程序用户的唯一标示),但是为了后面的功能需求,需要用户授权头像昵称等信息。在用户授权之后调用登录请求将用户数据保存到数据库中。
图5-20 登录流程图
(2)用户激活设备
用户与设备之间的关系是多对多的关系,即一个用户可以拥有多台设备,一台设备可以被多个用户激活,设备的第一激活者(设备第一次被激活)为管理员用户,设备再次被激活那么该用户为普通用户。管理员拥有对设备的绝对控制权限,管理员可以给该设备的其它使用者分配权限,管理员也可以给自己分配权限。
图5-21 激活流程图
(3)搜索蓝牙设备
用户激活设备之后就可以通过蓝牙控制设备了。微信小程序蓝牙开发的流程如下:
①初始化(开启)蓝牙模块wx.openBluetoothAdapter。
②搜索蓝牙设备(消耗大量资源,要及时结束)wx.startBluetoothDevicesDiscovery。
③结束搜索wx.stopBluetoothDevicesDiscovery
④与蓝牙设备建立连接wx.createBLEConnection
⑤获取蓝牙设备的服务列表wx.getBLEDeviceServices
⑥获取蓝牙设备的某个服务的特征值列表wx.getBLEDeviceCharacteristics
与特征值通信
⑦启用/关闭某个特征值的notify wx.notifyBLECharacteristicValueChange
读取特征值数据(读取到的数据通过特征值变化事件返回)wx.readBLECharacteristicValue
⑧向特征值写入数据wx.writeBLECharacteristicValue
⑨断开与蓝牙设备的连接wx.closeBLEConnection
⑩停用(关闭)蓝牙模块wx.closeBluetoothAdapter
图5-22 连接蓝牙流程图
(4)数据传输及安全验证
控制数据在传输过程中要先进行包装再进行加密加密之后再加上起始字符和结束字符之后再进行传输。具体流程如下图所示:
图5-23 数据传输程图
(5)修改数据
当用户授权登录,激活设备,得到设备之后即可对设备的数据进行修改,如传感器的名称,开关的名称,电机的名称,遥控器的名称及编码进行修改。当用户点击这些名称的时候,弹出修改框,用户自需要将新的名称输入其中点击确定就行了。
图5-24 修改数据流程图
(6)创建定时任务
当用户点击开关名称时,弹出选择框,用户可以选择开关在什么时候开启或关闭。当用户点击电机名称时,弹出选择框,用户可以选择电机在什么时候的值为多少。当用户长按遥控名称时,弹出选择框,用户可以选择遥控在什么时候发出指令。
图5-25 创建任务流程图
(7)执行定时任务
定时任务是将指令携带执行时间传输到服务器,服务器将指令和时间保存到数据库,服务器每隔30秒扫描一次数据库,查询小于当前系统时间的数据字段,将其指令通过MQTT协议发送到ESP32设备上,并将查询出来的数据库字段进行删除。
图5-26 执行任务程图
(8)设备授权
设备的管理员可以对其它用户进行授权,授权内容包括传感器数据显示,控开关控制,电机控制,定时任务,条件控制。授权之后用户将不能再获取权限之外的数据。
图5-27 授权设备程图
5.3.2界面设计与实现
(1)底部导航栏。
底部导航栏是用来切换不同的页面的,微信小程序的主要页面有蓝牙页面,设备页面,和个人中心页面。导航栏可以实现用户很
图5-28 底部导航栏图
(2)蓝牙搜索页面
①描述
蓝牙搜索连接页面,用来搜索蓝牙设备、显示蓝牙设备、连接蓝牙设备。用户可以查看本机的设备信息,还可以查看搜索到的蓝牙设备的信息。
②设计
蓝牙搜索连接页面由顶部栏,本机设备信息显示区域,按钮和设备显示区域组成。由于搜索到的设备数量不确定可能会撑出页面,那么要把搜索的蓝牙设备放到微信小程序的<scroll-view>组件当中。
③页面实现
图5-29 扫描蓝牙界面图
(3)蓝牙数据收发页面
①描述
蓝牙数据收发界面可以实时的显示当前接收的数据,还提供输入框可以输入数据,发送数据,提供断开蓝牙设备的功能。
②设计
页面功能主要是两个,查看接收的蓝牙数据,发送数据。页面顶部是导航栏,随后是数据显示区域,显示当前连接的蓝牙的设备名称、设备ID。数据接收区域封装在<scroll-view>组件中。中间有两个功能按钮分别是清空显示按钮,断开连接按钮。还有输入框和发送按钮,当用户点击输入框时跳出键盘,用户点击发送即可将数据发送到ESP32设备。
③页面实现
图5-30 蓝牙发送数据界面图
(4)蓝牙帮助页面
①描述
由于手机设备众多、系统版本不同、微信版本不同,那么用户在通过小程序连接ESP32设备过程中肯定会遇到各种各样的问题,这时就需要给用户一个连接指南,所有就需要一个帮助页面。
②设计
蓝牙帮助页面通过标题与解答的方式显示文本内容。用户通过标题查看自己遇到的问题,和解决方案。
③页面实现
图5-31 蓝牙帮助界面图
(4)设备页面
①描述
设备页面显示主要的功能列表,当用户点击功能项时跳转到对应的页面,设备页面由顶部栏、底部栏、功能项组成。
②设计功能项采用flex布局,每两项换一行显示,直到功能项全部显示完成。功能项目前有传感项、开关项、遥控项、电机项、条件项、任务项组成。
③实现
图5-32 设备界面图
(4)传感页面
①描述
传感页面显示ESP32设备的传感器数据,由两部分组成。上半部分显示气体检测、雨水检测、土壤湿度检测等数据。下半部分显示温度湿度数据。
②设计
因为传感数据由两部分组成,为了将数据全部显示出来需要将两部分都封装到<scroll-view>组件,为了使上半部分的传感项不超出屏幕还需要将上半部分也封装到<scroll-view>组件中,
③实现
图5-33 传感器界面图
(5)开关页面
①描述
开关页面一共显示40个开关。用户通过开关来控制ESP32设备上面的开关。
②设计
开关页面由40个开关项组成,每个开关项包括开关名称和开关选择器组成。为了保证页面不溢出把40个开关封装在<scroll-view>组件当中。
③实现
图5-34 开关控制界面图
(6)遥控页面
①描述
遥控页面用来控制ESP32的红外信号,ESP32通过红外信号可以用来遥控红外接收装置,如电视剧、空调、音响等设备。
②设计
用户点击红外遥控项即可让ESP32设备发出红外控制信号,而且每个红外遥控项的的编码都是可以修改的,那么1个开关就行了,但是由于来回的修改编码麻烦那么在本设计中一共有5个开关项。
③实现
图5-35 遥控界面图
(7)电机页面
①描述
ESP32设备的电机由电风扇,舵机等组成,这些电机通过PWM信号控制,可以实现控制电机的转速和转动角度。
②设计
由于PWM信号可以是不同的频率,那么不同的频率对应不同的电机状态,要实现选择不同的频率且方便操控,那么选择微信小程序提供的<slider>组件来实现。
③实现
图5-36 电机控制界面图
(8)条件页面
①描述
ESP32设备有很多自动控制的功能,这些功能实现语句是“当什么条件满足时执行什么动作”,这些条件的值是可以改变的,条件页面就是用来修改这些条件的。
②设计
要修改条件就要知道条件有哪些,以及条件所绑定的是什么,目前设置有3个条件分别是:当传感的值大于或小于某个值的时候蜂鸣器发出声音,当传感器的值当传感的值大于或小于某个值的时候电机的转速为多少,当活体检测到活物时开关开启或关闭。实现这些功能需要用到微信小程序提供的<picker>选择器组件。封装条件选项。
③实现
图5-37 触发设置界面图
(9)任务界面
①描述
任务界面是用来查看管理任务的,可以查看当前设备的所有未执行的任务。
②设计
页面由顶部栏和任务项组成,由于任务的数量不确定为了保证任务数量过多不超出屏幕,需要将任务项封装到<scroll-view>组件中。任务项由任务标题、任务执行时间,任务内容。
③实现
图5-38 任务界面图
(10)个人中心界面
①描述
个人中心显示当前用户的一些数据如头像昵称等,提供功能列表。
②设计
个人中心界面由两个部分组成,上部分是用户数据显示,下半部分是功能列表,用户数据有用户头像和用户昵称竖排显示。功能列表有激活设备、设备联网、设备授权、使用说明等。
③实现
图5-39 个人中心界面图
(11)激活设备页面
①描述
用户要使用设备必须先激活设备,激活设备页面就是用来激活设备的。
②设计
激活设备需要输入设备激活码,那么就需要一个输入框和一个激活按钮。
③实现
图5-40 激活设备界面图
(12)设备联网页面
①描述
激活设备成功之后用户即可通过蓝牙方式控制ESP32设备。如果要通过网络控制那么需要让ESP32设备连接上网络,
②设计
激活设备需要输入设备激活码,那么就需要一个输入框和一个激活按钮。
③实现
图5-41 配置WiFi界面图
(13)设备管理页面
①描述
用户与设备是多对多的关系,那么需要一个页面来切换不同的设备,如果用户是管理员那么还可以给其它用户设置设备使用权限。
②设计
设备管理页面顶部是导航栏,功能页面需要显示用户已经激活的所有设备,还需要显示当前设备的所有使用者的头像。为了防止页面超出范围将设备封装在<scroll-view>组件当中。
③实现
图5-42 设备管理界面图
(14)使用说明页面
①描述
当用户使用小程序遇到不懂的情况,可以通过使用说明界面解答自己的疑惑。
②设计
为了让用户可以快速的找到帮助文档,功能页面采用左右两个部分组成,左边是目录,右边是具体说明。用户通过目录可以快速的找到自己想看的文档。为了实现这样的布局需要使用<scroll-view>组件。
③实现
图5-43 使用说明界面图
成品展示
6.1 ESP32设备硬件展示
(1)硬件正面展示
图6-1 硬件连接正面图
(2)硬件背面展示
图6-2 硬件连接背面面图
(3)模型展示
图6-3 模块组装图
图6-4 最终完成图
6.2 微信小程序展示
打开手机微信扫描小程序码即可查看。
图6-5 小程序码
参考
[1]余杰.智能家居及其发展趋势[J].电子制作,2014(22):229.
[2] Stallings, William. Cryptography and network security: principles and practice. Pearson Education India, 2003.
[3]顾新萍. 基于微信小程序的智能家居控制系统设计与实现[D].青岛大学,2019.
[4]张伟. 智能家居终端互联系统的设计与实现[D].电子科技大学,2019.
[5]胡元. 基于ESP32的野外探险多功能信息传递系统[D].华中师范大学,2019.
[6]何经伟,刘玉媛.基于ESP32的办公环境信息监测系统[J].电子技术与软件工程,2019(24):153-154.
[7]王耀楠. 基于云服务平台的智能家居管理系统[D].电子科技大学,2019.