项目38 WiFi 智能家居#
1. 实验说明:
在前面的实验中,我们已经了解了ESP32的WiFi Station模式,WiFi AP模式和WiFi AP+Station模式等三种模式。
那么在本章实验中,我们将使用ESP32的WiFi Station模式通过APP连接WIFI来控制多个传感器/模块工作,实现WiFi智能家居的效果。
2. 实验器材:
|
|
|
|
|---|---|---|---|
ESP32*1 |
面包板*1 |
130直流电机模块*1 |
继电器模块*1 |
|
|
|
|
舵机*1 |
温湿度传感器*1 |
超声波传感器*1 |
4P转杜邦线公单*2 |
|
|
|
|
智能手机/平板电脑(自备)*1 |
面包板专用电源模块*1 |
6节5号电池盒*1 |
风扇叶*1 |
|
|
|
|
5号电池(自备)*6 |
MicroUSB线*1 |
3P转杜邦线公单*2 |
跳线若干 |
3. 实验接线图:
继电器 |
ESP32主板 |
温湿度传感器 |
ESP32主板 |
|---|---|---|---|
G |
G |
G |
G |
V |
5V |
V |
5V |
S |
IO32 |
S |
IO15 |
超声波传感器 |
ESP32主板 |
130 风扇模块 |
ESP32主板 |
|---|---|---|---|
Vcc |
5V |
G |
G |
Trig |
IO14 |
V |
5V |
Echo |
IO27 |
IN+ |
IO19 |
Gnd |
G |
IN- |
IO18 |
舵机 |
ESP32主板 |
|---|---|
红色线 |
5V |
棕色线 |
G |
橙色线 |
IO4 |

(注: 先接好线,然后在直流电机上安装一个小风扇叶片。)
4. 安装APP:
安装APP的方法请参照 项目37 WiFi测试 。这里就不重复讲解。
5. 添加xht11和ESP32Servo库:
本项目代码使用了名为 “xht11” 和 “ESP32Servo” 库。如果你还没有添加,请在学习之前添加它们。添加第三方库的步骤如下:
先添加xht11库:
打开Arduino IDE,单击 “项目” → “包含库” → “添加.ZIP库…”。在弹出窗口中找到该目录下名为 …\Arduino代码、库文件\Arduino库文件\xht11.ZIP 的文件,先选中 xht11.ZIP 文件,再单击 “打开”。


再添加ESP32Servo库:
打开Arduino IDE,单击 “项目” → “包含库” → “添加.ZIP库…”。在弹出窗口中找到该目录下名为 …\Arduino代码、库文件\Arduino库文件\ESP32Servo-0.8.0.ZIP 的文件,先选中 ESP32Servo-0.8.0.ZIP 文件,再单击 “打开”。


6. 项目代码:
//**********************************************************************************
/*
* 文件名 : WiFi 智能家居.
* 描述 : WiFi APP控制多个传感器/模块工作,实现WiFi智能家居的效果.
*/
#include <Arduino.h>
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiClient.h>
#include "xht11.h"
//gpio15
xht11 xht(15);
unsigned char dht[4] = {0, 0, 0, 0};
#include <ESP32Servo.h>
Servo myservo;
int servoPin = 4;
#define Relay 32
#define IN1 19 //IN1对应IN+
#define IN2 18 //IN2对应于IN-
#define trigPin 14
#define echoPin 27
int distance1;
String dis_str;
int ip_flag = 1;
int ultra_state = 1;
int temp_state = 1;
int humidity_state = 1;
String item = "0";
const char* ssid = "ChinaNet-2.4G-0DF0"; //用户wifi的名称
const char* password = "ChinaNet@233"; //用户wifi的密码
WiFiServer server(80);
String unoData = "";
void setup() {
Serial.begin(115200);
pinMode(Relay, OUTPUT);
myservo.setPeriodHertz(50);
myservo.attach(servoPin, 500, 2500);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
Serial.println("TCP server started");
MDNS.addService("http", "tcp", 80);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(Relay, LOW);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
WiFiClient client = server.available();
if (!client) {
return;
}
while(client.connected() && !client.available()){
delay(1);
}
String req = client.readStringUntil('\r');
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
item=req;
Serial.println(item);
String s;
if (req == "/")
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP32 at ";
s += ipStr;
s += "</html>\r\n\r\n";
Serial.println("Sending 200");
client.println(s);
}
else if(req == "/btn/0")
{
Serial.write('a');
client.println(F("turn on the relay"));
digitalWrite(Relay, HIGH);
}
else if(req == "/btn/1")
{
Serial.write('b');
client.println(F("turn off the relay"));
digitalWrite(Relay, LOW);
}
else if(req == "/btn/2")
{
Serial.write('c');
client.println("Bring the steering gear over 180 degrees");
myservo.write(180);
delay(200);
}
else if(req == "/btn/3")
{
Serial.write('d');
client.println("Bring the steering gear over 0 degrees");
myservo.write(0);
delay(200);
}
else if(req == "/btn/4")
{
Serial.write('e');
client.println("esp32 already turn on the fans");
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}
else if(req == "/btn/5")
{
Serial.write('f');
client.println("esp32 already turn off the fans");
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
else if(req == "/btn/6")
{
Serial.write('g');
while(Serial.available() > 0)
{
unoData = Serial.readStringUntil('#');
client.println("Data");
}
while(ultra_state>0)
{
Serial.print("Distance = ");
Serial.print(checkdistance());
Serial.println("#");
Serial1.print("Distance = ");
Serial1.print(checkdistance());
Serial1.println("#");
int t_val1 = checkdistance();
client.print("Distance(cm) = ");
client.println(t_val1);
ultra_state = 0;
}
}
else if(req == "/btn/7")
{
Serial.write('h');
client.println("turn off the ultrasonic");
ultra_state = 1;
}
else if(req == "/btn/8")
{
Serial.write('i');
while(Serial.available() > 0)
{
unoData = Serial.readStringUntil('#');
client.println(unoData);
}
while(temp_state>0)
{
if (xht.receive(dht)) {
Serial.print("Temperature = ");
Serial.print(dht[2],1);
Serial.println("#");
Serial1.print("Temperature = ");
Serial1.print(dht[2],1);
Serial1.println("#");
int t_val2 = dht[2];
client.print("Temperature(℃) = ");
client.println(t_val2);
}
temp_state = 0;
}
}
else if(req == "/btn/9")
{
Serial.write('j');
client.println("turn off the temperature");
temp_state = 1;
}
else if(req == "/btn/10")
{
Serial.write('k');
while(Serial.available() > 0)
{
unoData = Serial.readStringUntil('#');
client.println(unoData);
}
while(humidity_state > 0)
{
if (xht.receive(dht)) {
Serial.print("Humidity = ");
Serial.print(dht[0],1);
Serial.println("#");
Serial1.print("Humidity = ");
Serial1.print(dht[0],1);
Serial1.println("#");
int t_val3 = dht[0];
client.print("Humidity(%) = ");
client.println(t_val3);
}
humidity_state = 0;
}
}
else if(req == "/btn/11")
{
Serial.write('l');
client.println("turn off the humidity");
humidity_state = 1;
}
//client.print(s);
client.stop();
}
int checkdistance() {
digitalWrite(14, LOW);
delayMicroseconds(2);
digitalWrite(14, HIGH);
delayMicroseconds(10);
digitalWrite(14, LOW);
int distance = pulseIn(27, HIGH) / 58;
delay(10);
return distance;
}
//**********************************************************************************
特别注意:需要先将实验代码
中的 用户Wifi名称 和 用户Wifi密码 改成你们自己的Wifi名称和Wifi密码。
7. 实验现象:
特别注意:确保计算机网络,手机/平板的网络,ESP32主板,路由器,代码中输入你自己的WiFi名称和WiFi密码都必须是在同一个局域网(WiFi)下。

确认程序代码中的Wifi名称和Wifi密码修改正确后,编译并上传代码到ESP32主板上。
打开串口监视器,设置波特率为 115200,这样,串口监视器打印检测到的WiFi IP地址。(注意: 如果打开串口监视器且设置波特率为115200之后,串口监视器窗口没有显示如下信息,可以按下ESP32的复位键 

然后打开WiFi APP,在WIFI按钮前面的文本框中输入检测到的WIFI IP地址(例如,上面串口监视器检测到的IP地址:192.168.0.156),接着点击WIFI按钮来连接WiFi,同时WiFi IP地址前的文本框中会显示对应的WiFi IP地址“Hello from ESP32 at 192.168.0.156”。这样,就说明APP已经连接上了WiFi。(WiFi的IP地址有时候会改变,如果原来的IP地址不行,需要重新检测WiFi的IP地址)

APP已经连接上了WiFi后,开始进行如下操作:

(1)点击
按钮,继电器打开,APP上显示,模块上的指示灯点亮;再次点击
按钮,继电器关闭,APP上显示,模块上的指示灯不亮。
(2)点击
按钮,舵机转动180°,APP上显示
;再次点击
按钮,APP上显示
,舵机转动0°。
(3)点击
按钮,电机(带小风扇叶)转动,APP上显示
;再次点击
按钮,关闭电机,APP上显示
;
(4)点击
按钮,超声波传感器测距,在超声波传感器前放一个物体,APP上显示
(不同的距离显示不同的数字),说明此时物体离超声波传感器的距离为6cm;再次点击
按钮,关闭超声波,APP上显示
。
(5)点击
按钮,温湿度传感器测量环境中的温度,APP上显示
(不同的温度条件下显示不同的温度值),说明此时环境中的温度为30℃;再次点击
按钮,关闭温湿度传感器,APP上显示
。
(6)点击
按钮,温湿度传感器测量环境中的湿度,APP上显示
(不同的湿度条件下显示不同的湿度值),说明此时环境中的湿度为55%;再次点击
按钮,关闭温湿度传感器,APP上显示
。















