本章介绍使用 Qt 开发智能家居中的一个物联应用。简单直白的说就是通过云服务器远程控
制设备(与设备通信等)。本章可以直接做毕设,是毕设物联网项目的一大福音!本章将实现远
程点亮开发板 LED 作为一个项目实例。
在生活中,我们可能使用过 WIFI 智能插座这款产品。智能家居中常用来控制电器开关。
比如远程开热水器,远程打开空调,窗帘等等。这些 WIFI 智能插座的原理就是将 WIFI 插座注
册到云服务器上,然后通过手机的 APP 来访问云服务器,然后控制 WIFI 插座。嗯,原理我们
懂了。本章就是模仿?不,或者说是直接开发这样的一个项目。包括 WIFI 连网,注册到云服
务器上,编写 Qt UI 通过网络来与云服务器通信,然后再下发指令到这个连网的设备,与之通
信。恩本章的流程就是这些,带着这个项目流程,然后一步步看笔者是如何通过 Qt 实现的吧!
本章需要读者对正点原子的 wifi 模块 ATK-ESP8266 串口转 WIFI 有一定的了解。正点原子
提供了 STM32 与 ESP8266 模块通信的例程,如果学习过 STM32 与 ESP8266 模块通信的例程
的内容,理解起来则会更容易。建议参考文档:ATK-ESP8266 WIFI 用户手册_V1.x.pdf 及原子
云平台 API 文档 V1.2.pdf。
必备硬件
本章需要正点原子 ATK-ESP8266 串口转 WIFI 模块(免费接入原子云)。另外还需要加上
一个 USB-TTL 模块,外加一根 T 口 USB 连接线,可接入 PC(电脑)调试。
T 口连接线连接 USB-TTL 模块再连接 ATK-ESP8266 模块到 PC(电脑),用于在 PC(电脑)
上直接使用串口调试/测试此模块。
这里可能会有部分读者会问是否可以用其他 WIFI 模块,比如正点原子 Linux USB WIFI 模
块,或者直接使用开发板联网接入到云设备呢?答案是不可以的!只有一些特定的设备,需要
刷能接入云的固件才能接入服务器。
又有读者问是否可以直接购买一些 WIFI 插座来使用呢?答案是不可以的!因为这些 WIFI
插座也是一样,也是刷了固件,而且这些设备是连接到阿里云的。需要与特定的手机 APP 结合
使用才能注册到阿里云服务器。也就是不能拿来二次开发了!
恰好我们正点原子有物联网模块 ESP8266 与 4G DTU 模块。本章主要讲解如何通过正点原
子的串口转 WIFI ESP8266 模块来开发一个物联网的项目应用!
可选配件
本项目可以在正点原子 I.MX6U ALPHA | mini 开发板直接使用,下图为正点原子 ALPHA
开发板在底板上预留的 ATK MODULE 接口(串口接口)上的接法图。
特别提醒:如果反复实验不正确时,因为 ATK-MODULE 这个接口,KEY 和 LED 脚如果有其
他程序在使用,那么很可能会影响 ESP8266 模块的功能。刚好那两个脚接到了 ESP8266 的烧录
固件IO-0脚与复位RST脚上,所以我们可以用杜邦线将模块重新连接到这个座子上,只接VCC、
GND、TX 和 RX 脚即可!
要实现物联网功能,需要使用正点原子的 ATK-ESP8266 WIFI 模块。首先我们先测试正点
原子的 ATK-ESP8266 WIFI 模块是否正常使用,及能否正常连接原子云服务器。ATK-ESP8266
WIFI 用户手册_V1.3.pdf 手册第 2.2.3 小节硬件连接,将 ATK-ESP8266 WIFI 模块连接到 PC(电
脑),再查阅 ATK-ESP8266 WIFI 用户手册_V1.3.pdf 手册的第 2.2.9.1 小节,注册原子云帐号后,
添加设备,然后按 2.2.9.1 小节测试连接本地 WIFI(自己的路由器发出的 WIFI,注意不要使用
中文名或者有空格的 WIFI,确保路由器的 WIFI 能上网!)。请自行完成并成功连接到原子云。
请先测试个人的 ATK-ESP8266 模块是否正常使用,及正常连接云。原子云的设备需要先分
好组,各个设备命名如下。注意需要和笔者命名的名字一样,也就是至少有一个分组及一个名
字为“客厅灯”的设备,并记住编号及密码(密码由云生成,默认“12345678”)。
、
源码路径 4/01_smarthome/esp8266/esp8266.cpp,内容如下。默认使用的 WIFI 模块串口通
信波特率为 115200。在 Ubuntu 上设试 WIFI 模块时,一般串口名称为“ttyUSB0”,默认是没有
权限访问这个/dev/ttyUSB0 设备的。所以我们需要使用下面的指令修改权限。(注意:本例适用
于 I.MX6U Linux 开发板与 Ubuntu,Windows 不作测试!)。
sudo chmod 777 /dev/ttyUSB0
修改完成后查看源码内容如下。先看源码,不要急着运行!
/******************************************************************
Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
* @projectName esp8266
* @brief esp8266.cpp
* @author Deng Zhimao
* @email [email protected]
* @net www.openedv.com
* @date 2021-05-27
*******************************************************************/
1 #include "esp8266.h"
2 #include <unistd.h>
3 #include <QDebug>
4
5 Esp82266::Esp82266(QWidget *parent)
6 {
7 Q_UNUSED(parent)
8 /* 串口对象,用于与 Esp8266 模块通信 */
9 serialPort = new QSerialPort(this);
10
11 /* 定时器对象,用于定时发送设备在线的心跳包 */
12 timer = new QTimer();
13
14 /* led 对象,用于串口接收到云发过来的数据,然后控制板子的 LED */
15 led = new Led(this);
16
17 /* 设置串口名 */
18 #if __arm__
19 serialPort->setPortName("ttymxc2");
20 #else
21 serialPort->setPortName("ttyUSB0");
22 #endif
23
24 /* 设置波特率 */
25 serialPort->setBaudRate(115200);
26
27 /* 设置数据位数 */
28 serialPort->setDataBits(QSerialPort::Data8);
29
30 /* 设置奇偶校验 */
31 serialPort->setParity(QSerialPort::NoParity);
32
33 /* 设置停止位 */
34 serialPort->setStopBits(QSerialPort::OneStop);
35
36 /* 设置流控制 */
37 serialPort->setFlowControl(QSerialPort::NoFlowControl);
38
39 if (!serialPort->open(QIODevice::ReadWrite))
40 qDebug()<<"串口无法打开!可能正在被使用!"<<endl;
41 else {
42 qDebug()<<"串口打开成功!"<<endl;
43 }
44
45 /* 开始连接云 */
46 connectToClound();
47
48 connect(serialPort, SIGNAL(readyRead()),
49 this, SLOT(serialPortReadyRead()));
50
51 connect(timer, SIGNAL(timeout()),
52 this, SLOT(onTimerTimeOut()));
53 }
54
55 void Esp82266::serialPortReadyRead()
56 {
57 /* 接收缓冲区中读取数据 */
58 QByteArray buf = serialPort->readAll();
59
60 QString temp = QString(buf);
61 readData.append(temp);
62 qDebug()<<temp<<endl;
63
64 if (readData.contains("ready")) {
65 /* 如果复位成功 */
66 sendCmdToEsp8266("AT+CWMODE=1");
67 readData.clear();
68 }
69
70 if (readData.contains("OK") && readData.contains("AT+CWMODE")) {
71 qDebug()<<"设置 STA 模式成功"<<endl;
72 sendCmdToEsp8266("AT+CWJAP=\"ALIENTEK-YF\",\"15902020353\"");
73 qDebug()<<"开始连接 WIFI"<<endl;
74 readData.clear();
75 }
76
77 if (temp.contains("WIFI GOT IP")) {
78 qDebug()<<"连接 WIFI 成功"<<endl;
79 sleep(2);
80 /* 原子云的设备号及密码 */
81
sendCmdToEsp8266("AT+ATKCLDSTA=\"02314701717851074890\",\"12345678\"");
82 qDebug()<<"开始连接原子云请等待"<<endl;
83 }
84
85 if (temp.contains("CLOUD CONNECTED")) {
86 qDebug()<<"连接原子云成功"<<endl;
87 sleep(2);
88 /* 15s 就发送一次心跳包 */
89 timer->start(15000);
90 }
91
92 if (temp == "开")
93 led->setLedState(true);
94 else if (temp == "关")
95 led->setLedState(false);
96
97 }
98
99 Esp82266::~Esp82266()
100 {
101 serialPort->close();
102 delete timer;
103 timer = nullptr;
104 }
105
106 void Esp82266::sendCmdToEsp8266(QString cmd)
107 {
108 cmd = cmd + "\r\n";
109
110 QByteArray data = cmd.toUtf8();
111 serialPort->write(data);
112 }
113
114 void Esp82266::connectToClound()
115 {
116 /* 重启模块,注意若已经连接上原子云,
117 * 需要重新上电或者短接 RST 脚来复位模块 */
118 sendCmdToEsp8266("AT+RST");
119 }
120
121 void Esp82266::sleep(int second)
122 {
123 usleep(second * 1000000);
124 }
125
126 void Esp82266::sendTextMessage(QString message)
127 {
128 serialPort->write(message.toLatin1());
129 }
130
131 void Esp82266::onTimerTimeOut()
132 {
133 sendTextMessage("online");
134 qDebug()<<"发送设备在线心跳包"<<endl;
135 }
查看源码,我们可以知道以下重要内容。
第 72 行,“ALIENTEK-YF”是笔者处的路由器发出的 WIFI 热点名称,密码是“15902020353”。
请修改为自己的 WIFI 名称及连接密码!没有路由器,用手机开热点也可以。
第 81 行,是原子云上的“客厅灯”设备的编号“02314701717851074890”,及密码“12345678”,
请填写自己的设备编号,及密码,注意这个设备需要命名为“客厅灯”,后面程序需要使用到它!
按照上面的程序就容易地可以连接上原子云了。也无需熟读 ATK-ESP8266 WIFI 用户手册
_V1.3.pdf 手册。