相信各位小伙伴对ESP8266的使用已经很熟悉了,主要存在三种使用方式,AT固件方式:通过各种单片机或者ARM的串口驱动即可,安信可的开发环境编程(不推荐,开发环境难搭建),Arduino方式(各种功能都有库,推荐)。本案例以ESP8266作为服务端,利用Arduino开发环境搭建WebServer和TCPServer。WebServer、TCPServer最大的区别,各位小伙伴可以去回顾一下网络的知识,BS架构与CS架构的区别,在此不做过多的讲解。
一、整体的程序框架逻辑
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include "uFire_SHT20.h"
#include "webhtml.h"
#define LED_CONTROL 15
#define MAX_SRV_CLIENTS 2 //做多多少个客户端可以连接
#define SDA_PIN 2
#define SCL_PIN 14
const int16_t I2C_MASTER = 0x42;
const int16_t I2C_SLAVE = 0x08;
const byte DNS_PORT = 53; //DNS服务端口号,一般为53
WiFiServer server(23); //创建server 端口号是23
ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
WiFiClient serverClients[MAX_SRV_CLIENTS]; //定义最多多少个client可以连接本server(一般不要超过4个)
DNSServer dnsServer;
uFire_SHT20 sht20;
float Temerature;
float Humidity;
void setup()
{
ESP8266_Init();
startWebServer();
startTCPServer();
}
void loop() {
ReadHumiTemp();
dnsServer.processNextRequest();
esp8266_server.handleClient();
waitTCPClientConnect();
esp8266_server.handleClient();
receiveDataFromTCPClient();
esp8266_server.handleClient();
sendDataFromTCPClient();
esp8266_server.handleClient();
}
二、ESP8266相关的初始化,包括串口的初始化、温湿度传感器的初始化
void ESP8266_Init()
{
pinMode(LED_CONTROL,OUTPUT);//控制LED灯的引脚
digitalWrite(LED_CONTROL, HIGH);
Serial.begin(115200);//串口波特率设置
Wire.begin(SDA_PIN, SCL_PIN); //SHT20温湿度传感器(IIC接口)的初始化、配置
sht20.begin();
Serial.println();
/*ESP8266工作于AP模式,以下为设置IP、子网掩码等*/
IPAddress softLocal(192,168,1,1);
IPAddress softGateway(192,168,1,1);
IPAddress softSubnet(255,255,255,0);
WiFi.softAPConfig(softLocal, softGateway, softSubnet);
String apName = ("ESP8266_"+(String)ESP.getChipId()); // 设置WIFI名称
const char *softAPName = apName.c_str();
WiFi.softAP(softAPName, "1234567890"); // 创建wifi 名称 +密码 adminadmin
dnsServer.start(DNS_PORT, "www.hjjk.com", softLocal);//域名解析,将IP地址映射为域名
IPAddress myIP = WiFi.softAPIP(); // 输出创建的WIFI IP地址
Serial.print("AP IP address: ");
Serial.println(myIP);
Serial.print("softAPName: "); // 输出WIFI 名称
Serial.println(apName);
}
三、启动WebServer
void startWebServer()
{
esp8266_server.begin();
esp8266_server.on("/",handleRoot);
esp8266_server.on("/led_set",led_control);
esp8266_server.on("/tempread",temp_data);
esp8266_server.on("/humiread",humi_data);
}
四、启动TCPServer
void startTCPServer()
{
server.begin(); //启动server
server.setNoDelay(true);//关闭小包合并包功能,不会延时发送数据
}
五、读取温湿度
void ReadHumiTemp()
{
Temerature = sht20.temperature();
Humidity = sht20.humidity();
}
六、WebServer相关
void handleRoot()
{
esp8266_server.send(200, "text/html", String(HOME_SENSOR_DATA));
}
void temp_data()
{
char temp[7];
sprintf(temp, "%.2f",Temerature);
//Serial.println(temp);
esp8266_server.send(200, "text/plane", temp);
}
void humi_data()
{
char humi[7];
sprintf(humi, "%.2f",Humidity);
esp8266_server.send(200, "text/plane", humi);
}
void led_control()
{
String state = "灭";
String act_state = esp8266_server.arg("state");
if(act_state == "1")
{
digitalWrite(LED_CONTROL,LOW);// 改变LED的点亮或者熄灭状态
Serial.print("LEDON");
state = "亮";
}
else if(act_state == "0")
{
digitalWrite(LED_CONTROL,HIGH);// 改变LED的点亮或者熄灭状态
Serial.print("LEDOFF");
state = "灭";
}
else
{
}
esp8266_server.send(200, "text/plane", state);
}
WebServer相关的文件除了还包括一个头文件webhtml.h,即主要包括h5及Ajax(异步刷新)相关的东西,代码如下
const char HOME_SENSOR_DATA[] = R"=====(
<html><head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>室内环境监控</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0'/>
<style type="text/css">
.button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
</style>
<body style="background-color: #f9e79f ">
<center>
<div>
<br><br><br>
<h1>基于WiFi的室内环境监控系统</h1>
<button class="button" onclick="send(1)">开灯</button>
<button class="button" onclick="send(0)">关灯</button><BR>
</div>
<br>
<div><h2>
温度: <span id="temp_val">0</span>
<span id="Tdanwei"> ℃</span><br><br>
湿度: <span id="humi_val">0</span>
<span id="Hdanwei"> %RH</span><br><br>
LED 状态: <span id="state">灭</span>
</h2>
</div>
<script>
function send(led_sts)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("state").innerHTML = this.responseText;
if(this.responseText=="亮")
{
window.alert('LED灯已打开!');
}
else if(this.responseText=="灭")
{
window.alert('LED灯已关闭!');
}
else
{
}
}
};
xhttp.open("GET", "led_set?state="+led_sts, true);
xhttp.send();
}
setInterval(function()
{
getTempData();
getHumiData();
}, 700);
function getTempData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("temp_val").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "tempread", true);
xhttp.send();
}
function getHumiData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("humi_val").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "humiread", true);
xhttp.send();
}
</script>
</center>
</body>
</html>
)=====";
七、TCPServer相关
//等待TCP客户端的连接,在连接成功后读取客户端的控制指令
void receiveDataFromTCPClient()
{
uint8_t i;
String readbuf = "";
for (i = 0; i < MAX_SRV_CLIENTS; i++) {
if (serverClients[i] && serverClients[i].connected()) {
if (serverClients[i].available()) {
//serverClients[i].available() 判断指定客户端是否有可读数据
while (serverClients[i].available()) {
readbuf += char(serverClients[i].read());
if(readbuf == "LEDON")
{
digitalWrite(LED_CONTROL, LOW);
Serial.print("LEDON");
}
else if(readbuf == "LEDOFF")
{
digitalWrite(LED_CONTROL, HIGH);
Serial.print("LEDOFF");
}
else
{
}
}
}
}
}
}
//将采集到的温湿度数据下放给TCPClient
void sendDataFromTCPClient()
{
uint8_t i;
uint8_t sbuf[5];
sbuf[0] = ((int)(Temerature*100))/100;
sbuf[1] = ((int)(Temerature*100))%100;
sbuf[2] = ((int)(Humidity*100))/100;
sbuf[3] = ((int)(Humidity*100))%100;
sbuf[4] = '\n';
//push UART data to all connected telnet clients
for (i = 0; i < MAX_SRV_CLIENTS; i++) {
if (serverClients[i] && serverClients[i].connected()) {
serverClients[i].write(sbuf, 5);//向客户端发送数据
delay(1);
}
}
}
八、运行效果展示
1、Web展示温湿度数据及控制LED灯
将程序编译无误后烧录至ESP8266,复位后,将手机或计算机接入ESP8266形成的局域网,使用浏览器访问192.168.1.1(模块IP)或者www.hjjk.com(DNS映射)+端口号(本程序为80,HTTP默认端口号,所以可以省略),如下
?
2、手机App展示温湿度数据及控制LED灯
?关于使用AndroidStudio进行App开发,下期进行讲解!
|