问题描述
搭建一个简单的网页,控制ESP8266(安信可NodeMCU)点亮熄灭LED
问题思路
使用ESP8266,做一个简单的服务器。渲染出一个网页,处理网页上的按键请求,即可控制led。
开发环境
IDE
开发板:我用的NodeMCU ESP8266 安信可 ESP-12F开发板
代码
/**********************************************************************
项目名称/Project : 基本的服务器
程序名称/Program name : Web_Server
程序目的/Purpose : 搭建一个简单的网页,控制ESP8266点亮熄灭LED
***********************************************************************/
#include <ESP8266WiFi.h> // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h> // ESP8266WiFiMulti库
#include <ESP8266WebServer.h> // ESP8266WebServer库
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
ESP8266WebServer esp8266_server(80); // 建立ESP8266WebServer对象,对象名称为esp8266_server
// 括号中的数字是网路服务器响应http请求的端口号
// 网络服务器标准http端口号为80,因此这里使用80为端口号
// 添加几个可用的ap,WiFi重启后,自动连接信号最强的
void add_user_AP(void)
{
//通过addAp函数存储 WiFi名称 WiFi密码
wifiMulti.addAP("hh", "12345678");
wifiMulti.addAP("hh2", "87654321"); // 这3个WiFi网络名称分别是hh, hh2, hh3。
wifiMulti.addAP("hh3", "13572468"); // 这3个WiFi的密码分别是12345678,87654321,13572468。
// 此处WiFi信息只是示例,请在使用时将需要连接的WiFi信息填入相应位置。
}
// 等待连接成功
void wait_connect_ok(void)
{
int i = 0;
// wifiMulti.run()自动搜索addAP函数所存储的WiFi,并连接最强的那一个WiFi信号。
// 连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。
while (wifiMulti.run() != WL_CONNECTED)
{
delay(1000);
Serial.print(i++);
Serial.println('Waiting to connect to the network...');
}
}
// 打印连接信息
void print_connect_info(void)
{
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n'); // WiFi连接成功后
Serial.print("Connected to "); // ESP8266开发板将通过串口监视器输出。
Serial.println(WiFi.SSID()); // 连接的WiFI名称
Serial.print("IP address:\t"); // 以及
Serial.println(WiFi.localIP()); // ESP8266开发板的IP地址
}
//启动网络服务功能
void start_web_server(void)
{
esp8266_server.begin(); // 启动网络服务
esp8266_server.on("/", handleRoot); // 网站根目录,回调函数handleRoot
esp8266_server.on("/led_contrl", HTTP_POST, handleLED); // 设置处理LED控制请求的函数'handleLED'
esp8266_server.onNotFound(handleNotFound); // 找不到,回调函数handleNotFound
Serial.println("HTTP esp8266_server started"); // 告知用户ESP8266网络服务功能已经启动
}
void setup(void)
{
Serial.begin(9600); // 启动串口通讯
pinMode(LED_BUILTIN, OUTPUT); //设置内置LED引脚为输出模式以便控制LED
// 添加几个可用的ap,WiFi重启后,自动连接信号最强的
add_user_AP();
// 等待连接成功
wait_connect_ok();
// 打印连接信息
print_connect_info();
// 启动网络服务功能
start_web_server();
}
/* 主循环 */
void loop(void)
{
esp8266_server.handleClient(); // 处理http服务器访问
}
// 拼接显示网页
String show_html(bool station)
{
String html = "<!DOCTYPE html>";
html += "<html lang =\"zh-cn\">";
html += "<head>";
html += "<meta charset=\"UTF-8\">";
html += "<title>LED_CONTRL</title>";
html += "<style>";
html += "* {padding: 0;margin: 0;vertical-align: top;}";
html += "div {margin: 10px auto;width: 100px;}";
if (!station)
html += "span {display: inline-block;margin: 2px;background-color: blue;border-radius: 8px;width: 16px;height: 16px;}";
else
html += "span {display: inline-block;margin: 2px;background-color: black;border-radius: 8px;width: 16px;height: 16px;}";
html += "input {width: 60px;height: 20px;}";
html += "</style>";
html += "<title>ESP8266-LED</title>";
html += "</head>";
html += "<body>";
html += "<form action=\"/led_contrl\" method=\"post\">";
html += "<div><span></span><input type=\"submit\" value=\"LED\"></div>";
html += "</form>";
html += "</body>";
html += "</html>";
return html;
}
// 设置网站根目录函数
void handleRoot()
{
String html = show_html(digitalRead(LED_BUILTIN));
//处理网站根目录“/”的访问请求
esp8266_server.send(200, "text/html", html); // ESP8266开发板将调用此函数。
}
//处理LED控制请求的函数'handleLED'
void handleLED()
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // 改变LED的点亮或者熄灭状态
esp8266_server.sendHeader("Location", "/"); // 跳转回页面根目录
esp8266_server.send(303); // 发送Http相应代码303 跳转
}
// 设置处理404情况的函数'handleNotFound'
void handleNotFound()
{ // 当浏览器请求的网络资源无法在服务器找到时,
esp8266_server.send(404, "text/plain", "404: Not found"); // ESP8266开发板将调用此函数。
}
实验现象
将代码上传到ESP8266
打开串口监视器,重启ESP8266。记录如下的ip地址。
浏览器输入这个IP。通过这个IP就可以控制LED了。
点击LED按钮,点亮LED。
网页
实物
再次点击LED按钮,熄灭LED。
网页
实物
代码解释
show_html函数就是将下面的html网页代码文本,逐行转换为字符串。
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>LED_CONTRL</title>
<style>
* {
padding: 0;
margin: 0;
vertical-align: top;
}
div {
margin: 10px auto;
width: 100px;
}
span {
display: inline-block;
margin: 2px;
background-color: blue;
border-radius: 8px;
width: 16px;
height: 16px;
}
input {
width: 60px;
height: 20px;
}
</style>
<title>ESP8266-LED</title>
</head>
<body>
<form action="/led_contrl" method="post">
<div><span></span><input type="submit" value="LED"></div>
</form>
</body>
</html>
html文本直接打开效果。
通过判断led的状态,简单修改按钮的颜色样式,即可左边圆圈的颜色修改,