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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6282|回复: 4

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

[复制链接]
发表于 2021-3-3 15:05 | 显示全部楼层 |阅读模式
好多例程都是耍流氓,各种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[sizeof(gif)];
     memcpy_P(gif_colored, gif, sizeof(gif));
    // Set the background to a random set of colors
     gif_colored[16] = millis() % 256;
     gif_colored[17] = millis() % 256;
     gif_colored[18] = 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>
)";

Screenshot_20210303_150129.jpg

 楼主| 发表于 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
 楼主| 发表于 2021-3-4 11:45 | 显示全部楼层
如果用了别人的APP和MQTT broker发现信号不好,还是用自家的局域网通过HTTP传输做控制靠谱
发表于 2021-4-9 20:00 | 显示全部楼层
大家好,index.h: No such file or directory  这是怎么意思
 楼主| 发表于 2021-4-27 21:27 | 显示全部楼层
在arduino IDE的主程序小红通过新建标签增加index.h 文件,将自动保存与主程序在同一路径下
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 00:57 , Processed in 0.165927 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表