在 ESP32 客户端和服务器之间发送数据
我正在尝试创建一个简单的 Web 界面,以通过接入点托管客户端的 ESP32 控制 NeoPixel 条带。到目前为止,我在网上找到的每个示例都演示了如何通过将状态附加到 URL 标头来切换 LED 的开/关,然后在服务器端使用该信息来调用切换物理 LED 的函数,但是,我正在尝试做一些更独特的事情。
我找不到一种方法将从 HTML 颜色选择器中检索到的 #hex 值通过 HTTP 传递回服务器,然后使用它来设置 NEOPIXEL 颜色。
我所做的与许多示例不同的一件事是,我让服务器通过使用此函数发送 HTML 页面来处理客户端,据我所知,该函数获取包含 HTML 代码的 index.h 文件并将其发送到服务器到客户端。但我不确定如何“逆转”这个过程,特别是对于“文本/变量”
这是我的服务器代码:
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <Adafruit_NeoPixel.h>
//HTML code header for the web page
#include "index.h"
#define PIN 13
//Initialize the web client server
WebServer server(80);
//Initialize NeoPixels
Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);
const char* ssid = "ESP32NeoPixelInterface";
const char* password = "password";
//temporary string to hold the HEX value of the color picker received from the web client
String header = "";
//Current time
unsigned long currentTime = millis();
//Previous time
unsigned long previousTime = 0;
//Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s); //Send web page
}
void UpdateNeoPixels() {
}
void setup(void) {
Serial.begin(115200);
Serial.println();
Serial.println("Booting Sketch...");
strip.begin();
strip.setBrightness(25);
//Connect to Wi-Fi network with SSID and password
Serial.print("Setting AP (Access Point)…");
//Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
//Start server
server.on("/", handleRoot); //This is display page
server.begin();
Serial.println("HTTP server started");
//Set pixel #1 to green to show that an active access point connection has been made
strip.setPixelColor(1, 100, 0, 0);
strip.show();
}
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void loop(void) {
server.handleClient();
}
这是客户端的头文件:
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>ESP32 NeoPixel Web Control</title>
</head>
<style>
.button {
display: inline;
padding: 10px 10px;
font-size: 2em;
cursor: pointer;
text-align: center;
text-decoration: none;
outline: none;
color: #fff;
background-color: #4CAF50;
border: none;
border-radius: 10px;
box-shadow: 0px 2px 10px -2px rgba(0,0,0,0.5);
}
.button:hover {background-color: #3e8e41}
.button:active {
background-color: #3e8e41;
box-shadow: 0px 2px 15px -2px rgba(0,0,0,0.75);
transform: translateY(2px);
}
.p1 {
font-family: "Monaco", monospace;
color: white;
font-size: 1em;
}
.container{
position: absolute;
}
.center1{
margin: auto;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.center2{
margin: auto;
position: absolute;
top: 60%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
</style>
<body bgcolor="#282c34">
<h1 class="p1">This web page is hosted remotley by an ESP32 server, change the color of the LED NeoPixels using the color picker and press "SUBMIT".</STYLE></h1>
<hr height="10px"/>
<div class="containter">
<div class="center1">
<input type="color" id="myColor" value="#ff0080">
</div>
<div class="center2">
<button class="button button1" align="center" onclick=SendColorValue()>SUBMIT</button>
</div>
</div>
<script>
function SendColorValue() {
var x = document.getElementById("myColor");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
};
//Send a request from client to server saying "hey update the color of the NeoPixels!"
xhttp.open("POST", "ColorValue", true);
xhttp.send(x.value);
}
</script>
</body>
</html>
)=====";
我基本上需要找到一种发送 x.value 的方法这是从颜色选择器框中检索回服务器的颜色值,并使用该值来设置 neopixel 颜色。
我见过的大多数示例仅涉及从客户端向服务器发送“布尔”类型数据,如下所示:
// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
Serial.println("GPIO 26 on");
output26State = "on";
digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
Serial.println("GPIO 26 off");
output26State = "off";
digitalWrite(output26, LOW);
}
I am trying to create a simple web interface to control a NeoPixel strip from an ESP32 hosting a client over an access point. Every example I've found on the web so far demonstrates how you can toggle LED's ON/OFF by appending the state to the URL header and then using that info on the server-side to then call a function that toggles the physical LEDs, however, I'm trying to do something a little more unique.
I cannot find a way to pass the #hex value retrieved from my HTML color picker over the HTTP back to the server and use this to set the NEOPIXEL color then.
One thing I'm doing differently than many examples out there is I'm letting the server handle the client by sending the HTML page using this function, which I understand takes my index.h file which contains the HTML code and sends it over the server to the client. But I'm not sure how to "reverse" this process, especially for a "text/variable"
This is my server code:
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <Adafruit_NeoPixel.h>
//HTML code header for the web page
#include "index.h"
#define PIN 13
//Initialize the web client server
WebServer server(80);
//Initialize NeoPixels
Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);
const char* ssid = "ESP32NeoPixelInterface";
const char* password = "password";
//temporary string to hold the HEX value of the color picker received from the web client
String header = "";
//Current time
unsigned long currentTime = millis();
//Previous time
unsigned long previousTime = 0;
//Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s); //Send web page
}
void UpdateNeoPixels() {
}
void setup(void) {
Serial.begin(115200);
Serial.println();
Serial.println("Booting Sketch...");
strip.begin();
strip.setBrightness(25);
//Connect to Wi-Fi network with SSID and password
Serial.print("Setting AP (Access Point)…");
//Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
//Start server
server.on("/", handleRoot); //This is display page
server.begin();
Serial.println("HTTP server started");
//Set pixel #1 to green to show that an active access point connection has been made
strip.setPixelColor(1, 100, 0, 0);
strip.show();
}
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void loop(void) {
server.handleClient();
}
and this is the header file for the client:
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>ESP32 NeoPixel Web Control</title>
</head>
<style>
.button {
display: inline;
padding: 10px 10px;
font-size: 2em;
cursor: pointer;
text-align: center;
text-decoration: none;
outline: none;
color: #fff;
background-color: #4CAF50;
border: none;
border-radius: 10px;
box-shadow: 0px 2px 10px -2px rgba(0,0,0,0.5);
}
.button:hover {background-color: #3e8e41}
.button:active {
background-color: #3e8e41;
box-shadow: 0px 2px 15px -2px rgba(0,0,0,0.75);
transform: translateY(2px);
}
.p1 {
font-family: "Monaco", monospace;
color: white;
font-size: 1em;
}
.container{
position: absolute;
}
.center1{
margin: auto;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.center2{
margin: auto;
position: absolute;
top: 60%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
</style>
<body bgcolor="#282c34">
<h1 class="p1">This web page is hosted remotley by an ESP32 server, change the color of the LED NeoPixels using the color picker and press "SUBMIT".</STYLE></h1>
<hr height="10px"/>
<div class="containter">
<div class="center1">
<input type="color" id="myColor" value="#ff0080">
</div>
<div class="center2">
<button class="button button1" align="center" onclick=SendColorValue()>SUBMIT</button>
</div>
</div>
<script>
function SendColorValue() {
var x = document.getElementById("myColor");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
};
//Send a request from client to server saying "hey update the color of the NeoPixels!"
xhttp.open("POST", "ColorValue", true);
xhttp.send(x.value);
}
</script>
</body>
</html>
)=====";
I basically need to find a way to send x.value which is the color value retrieved from the color picker box back to the server and use this value to set the neopixel color.
Most examples I've seen only deal with sending "boolean" type data to the server from the client such as this:
// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
Serial.println("GPIO 26 on");
output26State = "on";
digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
Serial.println("GPIO 26 off");
output26State = "off";
digitalWrite(output26, LOW);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了处理从客户端发送的 POST 路由,您需要在服务器上执行以下操作:
然后您必须处理参数(十六进制值),
将其交给例程来分割十六进制并设置 Led
并响应客户端,例如
所以整个事情看起来像:
子例程 setLedColor 看起来像
Comments (也适用于其他读者):
我个人不使用 ESP8266/ESP32 的 String 类,因为从长远来看(有时是几分钟)它会整理内存碎片并使设备崩溃。
因此,您应该从一开始就学习使用 char 数组和 char 处理来实现稳定使用,因此我建议使用以下代码:
在 setup(): 之前定义一个全局 char 数组:
并从客户端获取值
,这会导致以下路线:
然后 setLedColor 定义如下:
希望这个解决方案对您的项目有所帮助 - 并记住“字符串是邪恶的”;-)
For processing the POST route you send from your client you need something on the server like:
then you have to process the argument (the hex value)
hand it over to a routine for splitting the hex and setting the Led
and respond to the client like
so the whole thing would look like:
The sub-routine setLedColor looks something like
Comments (also for other readers):
I personally do not use String class with ESP8266/ESP32 because on the long run (which is sometimes a few minutes) it defragments the memory and crashes the device.
So you should learn from the start to use char arrays and char handling for stable usage so I would propose the following code:
Define a global char array before setup():
and getting the value from the client like
which leads to the following route:
and the setLedColor is then defined as follows:
Hope this solution helps your project - and remember "Strings are evil" ;-)