ESP8266 WebServer②瞬时开关控服务器:控制 GPIO 输出

4 篇文章 0 订阅

项目目标:1连接WiFi自动弹出网页

                 2通过网页控制LED。

项目硬件:Nodemcu板

开发环境:VScode  PlatformIO

主要技术: AJAX  CSS ESP8266 NodeMCU with VS Code and PlatformIO:上传文件到文件系统(LittleFS)

工程源码 

PlatformIO设置

[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
board_build.filesystem = littlefs
monitor_speed = 115200
upload_speed = 921600
lib_deps = 
	me-no-dev/ESPAsyncTCP@^1.2.2
	esphome/ESPAsyncWebServer-esphome@^2.1.0

     

PlatformIO源码:

#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif

#include <DNSServer.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include "ESPAsyncWebServer.h"

#include "FS.h"
#include <LittleFS.h>
const int led_output = 2;
DNSServer dnsServer;
AsyncWebServer server(80);


class CaptiveRequestHandler : public AsyncWebHandler {
public:
  CaptiveRequestHandler() {}
  virtual ~CaptiveRequestHandler() {}

  bool canHandle(AsyncWebServerRequest *request){
    //request->addInterestingHeader("ANY");
    return true;
  }

  void handleRequest(AsyncWebServerRequest *request) {
    request->send(LittleFS, "/index.html","text/html", false); //连接WiFi自动弹出认证页面
  }
};

void setupServer(){
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      request->send(LittleFS, "/index.html","text/html", false); 
      Serial.println("Client Connected");
  });
    
   // Receive an HTTP GET request
  server.on("/ON", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(led_output, LOW);
    request->send(200, "text/plain", "OK");
  });

  // Receive an HTTP GET request
  server.on("/OFF", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(led_output, HIGH);
    request->send(200, "text/plain", "OK");
  });
}

void setup(){
  //your other setup stuff...
  Serial.begin(115200);
  pinMode(led_output, OUTPUT);
  digitalWrite(led_output, HIGH);
  if(!LittleFS.begin()){
    Serial.println("An Error has occurred while mounting LITTLEFS");
    return;
  }
  
 
  Serial.println();
  Serial.println("Setting up AP Mode");
  WiFi.mode(WIFI_AP); 
  WiFi.softAP("esp-captive");
  Serial.print("AP IP address: ");Serial.println(WiFi.softAPIP());
  Serial.println("Setting up Async WebServer");
  setupServer();
  Serial.println("Starting DNS Server");
  dnsServer.start(53, "*", WiFi.softAPIP());
  server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP
  //more handlers...
  server.begin();
  Serial.println("All Done!");
}

void loop(){
  dnsServer.processNextRequest();  
}

代码原理

此代码与 ESP32 和 ESP8266 板兼容,但我们定义 LED 状态的部分除外。对于 ESP8266,与 ESP32 相比,板载 LED 的工作逻辑相反。要打开板载 LED,发送一个低信号,要关闭它,发送一个高信号。这与 ESP32 的情况相反。

引用库

首先,我们将包含该项目所需的所有必要库。由于此代码与 ESP32 和 ESP8266 兼容,因此这两个库(无线网络.hESP8266WiFi.h) 被定义。该库将有助于在我们的 ESP 模块与无线网络之间建立连接。我们还将导入我们之前安装的两个库,ESPAsyncWebServer库和ESPAsyncTCP库。 

#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif

 设置输出GPIO

然后,我们将定义变量 led_output 来保存连接板载 LED 的 GPIO 引脚,即,GPIO2.

const int led_output = 2;

创建 AsyncWebServer 对象

AsyncWebServer 对象将用于设置 ESP Web 服务器。我们将传递默认的 HTTP 端口 80 作为构造函数的输入。这将是服务器侦听请求的端口。

AsyncWebServer server(80);

 ESP32/ESP8266 处理请求

在本节中,我们将讨论我们的 ESP 板将如何处理不同 URL 上的请求。

/   请求

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
      request->send(LittleFS, "/index.html","text/html", false); 
      Serial.println("Client Connected");
  });

 /ON请求

server.on("/ON", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(led_output, LOW);
    request->send(200, "text/plain", "OK");
  });

 我们将使用server.on()服务器对象上的方法来监听传入的 HTTP 请求并相应地执行函数。GPIO2 的输出状态将通过 digitalWrite() 函数设置为 LOW。

/OFF  请求

// Receive an HTTP GET request
  server.on("/OFF", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(led_output, HIGH);
    request->send(200, "text/plain", "OK");
  });

 我们将使用server.on()服务器对象上的方法来监听传入的 HTTP 请求并相应地执行函数。GPIO2 的输出状态将通过 digitalWrite() 函数设置为HIGH。

要启动服务器,我们将在服务器对象上调用 begin()。

server.begin();

服务器网页源码

<!DOCTYPE HTML><html>
  <head>
    <title>ESP Web Server</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body { font-family: Times New Roman; text-align: center; margin:0px auto; padding-top: 30px;}
      .button {
        padding: 10px 20px;
        font-size: 24px;
        text-align: center;
        outline: none;
        color: #fff;
        background-color: #ff0522;
        border: none;
        border-radius: 15px;
        cursor: pointer;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -khtml-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        -webkit-tap-highlight-color: rgba(0,0,0,0);
      }  
      .button:hover {background-color: #ff0522 }
      .button:active {
        background-color: #1fe036;
        transform: translateY(2px);
      }
    </style>
  </head>
  <body>
    <h1>ESP瞬时开关服务器</h1>
    <button class="button" onmousedown="toggleCheckbox('ON');" ontouchstart="toggleCheckbox('ON');" onmouseup="toggleCheckbox('OFF');" ontouchend="toggleCheckbox('OFF');">瞬时开关:按压开启</button>
   <script>
   function toggleCheckbox(x) {
     var xhr = new XMLHttpRequest();
     xhr.open("GET", "/" + x, true);
     xhr.send();
   }
  </script>
  </body>

 定义按钮

现在,我们将创建瞬时开关按钮。我们将在里面定义按钮<button></button>标签。我们将提供不同的属性和文本,如下所示:

<button class="button" onmousedown="toggleCheckbox('ON');" ontouchstart="toggleCheckbox('ON');" onmouseup="toggleCheckbox('OFF');" ontouchend="toggleCheckbox('OFF');">Momentary Switch: Press to Turn ON</button>

 在按钮上将显示以下文本瞬时开关:按下开启. 除此之外,我们还将包括属性。

首先,类将包含瞬时开关的名称。在我们的例子中,我们将其命名为“按钮”。这将用于在设置网页样式时引用开关。

其次,onmousedown 是事件的属性。我们将调用toggleCheckbox()以 'ON' 作为参数的函数,以防按下按钮。这是我们稍后会谈到的 JavaScript 函数。通过此功能,将向 ESP32/ESP8266 板发出 HTTP GET 请求,将输出状态变为高电平。

第三,onmousestart 也将调用相同的函数与相同的参数toggleCheckbox('ON'). 这对于具有触摸屏的设备很有用功能。

第四,onmouseup 会调用toggleCheckbox()函数,但内部传递的参数是'OFF'。每当释放按钮时都会调用它。该函数将向 ESP 模块发出 GET 请求以将状态更改为 LOW。

最后,ontouchend 将用于具有触摸屏的设备。这将与 onmouseup 类似。

toggleCheckbox() 函数

function toggleCheckbox(x) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/" + x, true);
  xhr.send();
}

接下来,我们将定义toggleCheckbox()功能。这是我们在上面定义瞬时开关按钮的属性时调用的 JavaScript 函数。通过此函数,将向 ESP 模块发出关于打开或关闭 LED 的 HTTP GET 请求。每当按下或释放按钮时,它将创建 HTTP GET 请求。这将通过在 /ON 或 /OFF URL 上重定向它来完成。

在这个函数中,我们使用 XMLHttpRequest。这将允许我们在 JavaScript 中发出 HTTP 请求。要向我们发出 HTTP GET 请求,我们将遵循三个步骤:
首先,我们将创建一个 XMLHttpRequest,如下所示:

var xhr = new XMLHttpRequest();

其次,我们将使用xhr.open()方法。在其中,我们将传递三个参数。第一个参数指定 HTTP 方法的类型,在我们的例子中是 GET。第二个参数是 ESP32/ESP8266 请求的 URL。在我们的例子中,它将是 /ON 或 /OFF URL,具体取决于按钮的状态。最后一个参数是 true,它指定请求是异步的。

xhr.open("GET", "/" + x, true);

最后,我们将使用xhr.send()打开连接。我们的服务器(ESP32/ESP8266)现在可以在用户与按钮交互时接收 HTTP GET 请求。

xhr.send();

关于css

CSS :active 选择器

 .button:active {
        background-color: #1fe036;
        transform: translateY(2px);
      }

当按钮有效时,背景颜色设置为绿色,

CSS transform 属性

定义和用法

transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。

translateY(y)    定义转换,只是用 Y 轴的值。

网页初始状态,按钮没有按下

按钮按下状态:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

armcsdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值