ESP使用webserver实现本地控制

因为使用云服务有时候不可靠,那么离线控制就很重要。本文使用webserver实现本地网页控制。这样不需要再单独开发APP,有浏览器就可以控制。本文所有测试是靠ESP32。8266未测试。使用USE_8266控制。

核心代码如下:

html.h

#pragma once

const char *AutoConfigHTML = u8R"esp_html(
    <!DOCTYPE html>
<html>

<head>
    <meta charset="UTF8">
    <title>智能控制台</title>
</head>

<body style="font-size: 30px">

    <style>
        .inputText {
            height: 38px;
            font-size: 30px;
            line-height: 30px;
            padding-left: 15px;
            border-radius: 10px;
            background-color: #dff1f7;
            border: 2;
        }

        .inputText:focus {
            outline: none;
            background-color: #d6e4eb;
        }

        .buttonText {
            height: 38px;
            font-size: 30px;
            line-height: 30px;
            padding-left: 15px;
            border-radius: 10px;
            background-color: #FE5E08;
            border: none;
        }

        .buttonText:focus {
            outline: none;
            background-color: #FE5E08;
        }

        .buttonText:disabled {
            background-color: #c9c7c6;
        }
    </style>

    <center>
        <form>
            <input id="btn_test" type="button" class="buttonText" value="点我测试" onclick="config(this)"/>
            <br/>
            <label id="recvtxt"/>
        </form>
    </center>
    <script language="javascript">
        function config(sender) {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4) {
                    if (xmlhttp.status == 200) {
                        document.getElementById("recvtxt").innerText = "设置成功";                        
                    }
                    else {
                        document.getElementById("recvtxt").innerText = "设置失败";
                        document.getElementById("btnsendconfig").disabled = false;
                    }
                }
            }
            xmlhttp.ontimeout = function () {
                window.location.href = "about:blank";
                window.close();
            }
            xmlhttp.open("GET", "/Ctrl?btn_name=" + sender.id, true);
            xmlhttp.timeout = 5000;
            xmlhttp.send();
            document.getElementById("btnsendconfig").disabled = true;
        }
    </script>
</body>

</html>
)esp_html";

webctrl.h


#include <atomic>
#include <thread>
#include <functional>
#include "html.h"

#ifndef AUTOCFGSSID
#define AUTOCFGSSID "ESP_WIFI"
#endif
#ifndef AUTOCFGPSW
#define AUTOCFGPSW "12345678"
#endif

#ifdef USE_8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
using TagWebSERVER = ESP8266WebServer;
#else
#include <WiFi.h>
#include <WebServer.h>
using TagWebSERVER = WebServer;
#endif

using FunWebServerCallback = std::function<bool(const char *)>;

class CWebControl
{

protected:
    void HandleHtmlRoot()
    {
        m_ControlWebServer.send(200, "text/html", AutoConfigHTML);
    }

    void HandleHtmlContrl()
    {
        if (m_WebServerCallback)
        {
            bool bRet=m_WebServerCallback(m_ControlWebServer.arg("btn_name").c_str());
            m_ControlWebServer.send(bRet?200:500, "text/html", m_ControlWebServer.arg("btn_name").c_str());
        }
    }

public:
    CWebControl() : m_bRun(false)
    {
    }

    void Init()
    {
        WiFi.mode(WIFI_AP_STA); // 双模式
        WiFi.setAutoReconnect(true);

        IPAddress ip, gateway, subnet;
        ip.fromString("192.168.2.1");
        gateway.fromString("192.168.2.1");
        subnet.fromString("255.255.255.0");
        WiFi.softAPConfig(ip, gateway, subnet);

        WiFi.softAP(AUTOCFGSSID, AUTOCFGPSW);

        m_ControlWebServer.on("/", std::bind(&CWebControl::HandleHtmlRoot, this));
        m_ControlWebServer.on("/Ctrl", HTTP_GET, std::bind(&CWebControl::HandleHtmlContrl, this));
    }

    ~CWebControl()
    {
        Stop();
    }

    void Stop()
    {
        m_bRun = false;
        m_ControlWebServer.close();
        if (m_LoopThread.joinable())
        {
            m_LoopThread.join();
        }
    }

    void SetCallBack(FunWebServerCallback callback)
    {
        m_WebServerCallback = callback;
    }

    void Run()
    {
        Stop();
        m_bRun = true;
        m_ControlWebServer.begin(80);
        m_LoopThread = std::thread(std::bind([&]
                                             {
            while (m_bRun)
        {
            m_ControlWebServer.handleClient();
        } }));
    }

private:
    std::thread m_LoopThread;
    TagWebSERVER m_ControlWebServer;
    std::atomic_bool m_bRun;
    FunWebServerCallback m_WebServerCallback;
};

调用方法如下

// 这里定义热点名和密码,定义一定要在#include "webCtrl.h"前面
//连接如下热点 在浏览器访问 192.168.2.1 即可打开控制页面。当然IP地址可以在webCtrl.h修改成你想要的。
//#define AUTOCFGSSID "ESP_WIFI"
//#define AUTOCFGPSW "12345678"

// 如果使用8266取消下行注释
// #define USE_8266
#include "webCtrl.h"

// 我这里使用的是ESP32 s3.当然其它型号也是代码通用。因为这里我的板子有一颗RGB。使用它测试。请根据需要修改
#ifndef USE_8266
#include "RGB.h"
RGB rgb(1, 48);//注意我买的板子是48脚。你的板子未必是
#endif

CWebControl g_WebControl;

bool WebCtrlCallBack(const char *name)
{
    // btn_test这里需要修改HTML对应ID。我这里使用btn_test。添加按钮根据ID区分即可。
    if (strcmp(name, "btn_test") == 0)
    {
#ifndef USE_8266
        static bool trunOn = false;
        rgb.showRGB(trunOn = !trunOn, 0, 255, 100);
#endif
    }
    return true;
}

void setup()
{
    // put your setup code here, to run once:
    g_WebControl.Init();
    g_WebControl.SetCallBack(std::bind(WebCtrlCallBack, std::placeholders::_1));
    g_WebControl.Run();

#ifndef USE_8266
    rgb.begin(50);
#endif
}

void loop()
{
    // put your main code here, to run repeatedly:
}

工程代码下载:

【免费】esp32使用网页实现本地控制资源-CSDN文库

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值