Arduino程序内嵌html生成web页通过ESP模块实现无线控制-Arduino中文社区 - Powered by Discuz! Archiver

armduino 发表于 2021-3-3 15:05

Arduino程序内嵌html生成web页通过ESP模块实现无线控制

好多例程都是耍流氓,各种bug,本例无
支持原创,乐于分享!
/*
*假设您的ESP8266开发板IP地址是192.168.0.111,那么接下来您可以通过浏览器输入该IP地址
*当ESP8266开发板建立网络服务器以后,每当有客户端APP向服务器发送HTTP请求时,我们可以利用on函数来设置HTTP请求回调函数
*对于IE浏览器,同时按下alt+热键后,松开,再按enter才能激活on/off,热键定义在文件index.h中
*In avr-libc-1.8.0, the function memcpy_P() is defined in avr-libc-1.8.0/libc/pmstring/memcpy_P.S
*ingroup avr_pgmspace   
*fn void *memcpy_P(void *dest, PGM_VOID_P src, size_t n)  
*The memcpy_P() function is similar to memcpy(), except the src string resides in program space.
*The memcpy_P() function returns a pointer to dest.
*
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include "index.h"

#ifndef STASSID//Service Set Identifier 服务集标识
#define STASSID "TP-LINK_2F98"
#define STAPSK"1122334455"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

ESP8266WebServer espServer(80);//定义网页服务器对象及端口,网络服务器标准http端口号为80

const int led1 = 13;
const int led2 = 14;
//const int led = 2;

void handleRoot() {//处理网站根目录"/"的访问请求,返回PAGE_INDEX页面
   //digitalWrite(led, 1);
   //server.send(200, "text/plain", "hello from esp8266!");
   //espServer.send(200, "text/html", "<form action=\"/LED\" method=\"POST\"><input type=\"submit\" value=\"Toggle LED\"></form>");   // NodeMCU将调用此函数。访问成功返回200状态码,返回信息类型text/html
   espServer.send(200,"text/html",PAGE_INDEX);// 文本格式为html,PAGE_INDEX的定义在“index.h”头文件中
   //delay(1000);
   //digitalWrite(led, 0);
}

void handleNotFound() {
   digitalWrite(LED_BUILTIN, 1);
   String message = "File Not Found\n\n";
   message += "URI: ";
   message += espServer.uri();
   message += "\nMethod: ";
   message += (espServer.method() == HTTP_GET) ? "GET" : "POST";
   message += "\nArguments: ";
   message += espServer.args();
   message += "\n";
   for (uint8_t i = 0; i < espServer.args(); i++) {
   message += " " + espServer.argName(i) + ": " + espServer.arg(i) + "\n";
   }
   espServer.send(404, "text/plain", message);
   digitalWrite(LED_BUILTIN, 0);
}

void handleLED(){
   digitalWrite (LED_BUILTIN,!digitalRead(LED_BUILTIN));// 改变LED的点亮或者熄灭状态
   digitalWrite (led2,!digitalRead(led2));
   espServer.sendHeader("Location","/");          //Location 跳转回页面根目录
   espServer.send(303);                           // 发送Http相应代码303 跳转
   //espServer.send(200, "text/plain", "this works as well");
}

void setup(void) {
   pinMode (led1, OUTPUT);
   pinMode (led2, OUTPUT);
   pinMode (LED_BUILTIN,OUTPUT);
   digitalWrite(led2, 0);
   digitalWrite(LED_BUILTIN, 1);

   Serial.begin(115200);
   Serial.setDebugOutput(true);
   WiFi.begin(ssid, password);
   WiFi.mode(WIFI_STA);
   Serial.println("");

// Wait for connection
   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());
   //MDNS.begin ("esp8266");
   if (MDNS.begin("esp8266")) {
   Serial.println("MDNS responder started");
   }
   espServer.on ("/",HTTP_GET,handleRoot);    //访问网站的根目录,处理GET请求,执行handleRoot函数
   espServer.on ("/LED",HTTP_POST,handleLED); //设置处理LED控制请求函数,处理POST请求

   espServer.on ("/", handleRoot);            //处理首页链接请求的事件,例如192.168.0.111/index.html
   espServer.on ("/index.html",handleRoot);   //效果同上
//测试页
   espServer.on ("/inline", []() {            //引入Lambda表达式编写内嵌的匿名函数
                  espServer.send(200, "text/plain", "this works is well");
                  });
// 定义控制功能
   espServer.on ("/switch", []() {
               if (espServer.hasArg("led")){//请求中是否包含有led的参数
                  String state=espServer.arg("led");//获得led参数的值<a href="/switch?led=on">
                     if (state=="on"){
                     digitalWrite(led1,HIGH);
                     //espServer.send(200,"text/html","Pin13 is on"); return;
                     }
                     else if (state=="off"){
                     digitalWrite(led1,LOW);
                     //espServer.send(200,"text/html","Pin13 is off"); return;
                     }
                     else{
                     state="Unkown state value";
                     //espServer.send(200,"text/html","unknown state"); return;//led其它(状态)值
                     }
                     espServer.send(200,"text/html","<h1> LED is<font color=\"red\"> " + state + " </font> <br> The lamp is OK! </h1> <br>" + "<h2> Enjoy! </h2>");                     
               }
               else
               espServer.send(200,"text/html","state not found");
               });
// 输出一个笑脸,没有意义
   espServer.on ("/gif", []() {
   static const uint8_t gif[] PROGMEM = {
            0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01,
            0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00,
            0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d,
            0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c,
            0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b
            };
   char gif_colored;
   memcpy_P(gif_colored, gif, sizeof(gif));
    // Set the background to a random set of colors
   gif_colored = millis() % 256;
   gif_colored = millis() % 256;
   gif_colored = millis() % 256;
   espServer.send(200, "image/gif", gif_colored, sizeof(gif_colored));
   });
//处理找不到指定路径的事件
   espServer.onNotFound(handleNotFound);

   espServer.begin();
   Serial.println("Awesome! HTTP esp8266_server started!");
}

void loop(void) {
espServer.handleClient();//检查有没有客户端设备通过网络向ESP8266网络服务器发送请求
MDNS.update();
}

//通过新建标签增加index.h 文件,与主程序在同一路径下
//不能使用=====R"()"=====
//注意要使用半角符号的引号
//onclick="alert('string ');" 最后面的分号必须有-->

static const char PAGE_INDEX[] PROGMEM = u8R"(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--meta http-equiv="refresh" content="20"-->
<title>物联网控制页面</title>
<!--没有效果link rel="stylesheet" -->
<style>
html{
      text-align:center;
      }
</style>
</head>
<body bgcolor="grey">

<h1> <font color="blue"> <u> ESP8266物联网 </u> </font> </h1>
<h2 style="background-color:black"><font color="white"> Home Light Switch</font></h2>

<a href="/switch?led=on"accesskey="Q"> <button type="button"> <font color="red">打开1#灯</font> </button> </a>
<a href="/switch?led=off" accesskey="E"> <button type="button"> <font color="blue">关闭1#灯</font> </button> </a><br>

<form action="/LED" method="POST"><input type="submit" value="2#灯开关"></form><br>
<button type="button">占位备用</button>

<p style="background-color: green">测试阶段</p>
</body>
</html>
)";



armduino 发表于 2021-3-4 11:43

SDK:2.2.2-dev(38a443e)/Core:2.7.3-3-g2843a5ac=20703003/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
scandone

wifi evt: 2
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 3
cnt

connected with TP-LINK_2F98, channel 1
dhcp client start...
wifi evt: 0
ip:192.168.0.120,mask:255.255.255.0,gw:192.168.0.1
wifi evt: 3
.
Connected to TP-LINK_2F98
IP address: 192.168.0.111
MDNS responder started
Awesome! HTTP esp8266_server started!
pm open,type:2 0

armduino 发表于 2021-3-4 11:45

如果用了别人的APP和MQTT broker发现信号不好,还是用自家的局域网通过HTTP传输做控制靠谱

bing` 发表于 2021-4-9 20:00

大家好,index.h: No such file or directory这是怎么意思

armduino 发表于 2021-4-27 21:27

在arduino IDE的主程序小红通过新建标签增加index.h 文件,将自动保存与主程序在同一路径下
页: [1]
查看完整版本: Arduino程序内嵌html生成web页通过ESP模块实现无线控制