Arduino IDE/ESP8266:为什么必须按两次按钮才能获得正确的输出?
Arduino IDE/ESP8266: Why does a button have to be pressed twice to get the correct output?
我一直在自学 ESP8226 编程,特别是 ESP8226-12F。我有这个基于在线示例的脚本:
#include <ESP8266WiFi.h>
WiFiServer server(80); //Initialize the server on Port 80
void setup() {
WiFi.mode(WIFI_AP); //Our ESP8266-12E is an AccessPoint
WiFi.begin("***","***"); // Provide the (SSID, password);
Serial.begin(115200); //Start communication between the ESP8266-12E and the monitor window
IPAddress HTTPS_ServerIP= WiFi.localIP(); // Obtain the IP of the Server
Serial.print("Server IP is: "); // Print the IP to the monitor window
Serial.println(HTTPS_ServerIP);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
server.begin(); // Start the HTTP Server
}
void loop() {
String status;
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("Somebody has connected :)");
//Read what the browser has sent into a String class and print the request to the monitor
String request = client.readString();
Serial.println(request);
// Handle the Request
if (request.indexOf("/CLOSE") != -1) {
Serial.println(request.indexOf("/CLOSE"));
status = "CLOSED";
}
if (request.indexOf("/OPEN") != -1) {
Serial.println(request.indexOf("/OPEN"));
status = "OPEN";
}
Serial.println(status);
// The HTML
String s = "HTTP/1.1 200 OK";
s += "Content-Type: text/html\r\n\r\n";
s += "<!DOCTYPE html><html><head><meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'\"> <meta name=\"referrer\" content=\"no-referrer\" /></head><body>";
s += "<br><input type=\"button\" name=\"b1\" value=\"OPEN DOOR\" onclick=\"javascript:location.href='/OPEN'\">";
s += "<br><input type=\"button\" name=\"b2\" value=\"CLOSE DOOR\" onclick=\"javascript:location.href='/CLOSE'\">";
if(status == "OPEN") {
s+= "<br><br><p>OPEN</p>";
} else {
s+= "<br><br><p>CLOSED</p>";
}
s += "</body></html>\n";
client.flush(); //clear previous info in the stream
client.print(s); // Send the response to the client
delay(1);
Serial.println("Client disonnected");
您会看到初始 HTTP 响应创建了两个按钮:OPEN DOOR 和 CLOSE DOOR。
我遇到的问题是必须按两次关闭按钮才能使草图输出 "CLOSED"。
这是串行监视器的输出。
1: 第一次浏览到 http://10.0.1.92:
Somebody has connected :)
GET / HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Client disonnected
2: 按打开按钮 http://10.0.1.92/OPEN 显示 "OPEN"
Somebody has connected :)
GET /OPEN HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://10.0.1.92/
4 // This is value of request.indexOf("/CLOSE")
OPEN
Client disonnected
3: 按CLOSE http://10.0.1.92/CLOSE 仍然显示"OPEN"
Somebody has connected :)
GET /CLOSE HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://10.0.1.92/OPEN
4
371 // No idea where this comes from
OPEN
Client disonnected
4:第二次按CLOSE,显示"CLOSED":
Somebody has connected :)
GET /CLOSE HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://10.0.1.92/CLOSE
4
CLOSED
Client disonnected
为什么要按两次关闭按钮才能显示 "CLOSED"?这是逻辑问题,还是 HTTP 问题,还是两者的某种结合?
这是可疑的:
if(status == "OPEN"){
s+= "<br><br><p>"+status+"</p>";
} else {
s+= "<br><br><p>"+status+"</p>";
}
如果两个选项相同,if
语句是什么?
另外 Referer
显示了三个不同的值,而根据您的设计,一个人会期望两个值。我想知道你最初在哪里设置这个二进制状态机的状态?
编辑:
所以 OP 更新了源代码。
if(status == "OPEN") {
s+= "<br><br><p>OPEN</p>";
} else {
s+= "<br><br><p>CLOSED</p>";
}
对战:
if (request.indexOf("/CLOSE") != -1) {
Serial.println(request.indexOf("/CLOSE"));
status = "CLOSED";
}
if (request.indexOf("/OPEN") != -1) {
Serial.println(request.indexOf("/OPEN"));
status = "OPEN";
}
你现在看到它们在逻辑上有何不同了吗?
这可能意味着当状态机启动时,由于它没有打开,所以它在顶部块中关闭但在底部块中没有关闭。按下下一个按钮将其更改为打开,然后第二次将其更改为关闭?这可能是正在发生的事情吗?
问题是这些语句:
if (request.indexOf("/CLOSE") != -1){ . . .
if (request.indexOf("/OPEN") != -1){ . . .
如果您查看响应字符串,您会发现那些 if 语句与 GET /OPEN 或 GET /CLOSED 以及 Referer 相匹配:http://10.0.1.92/CLOSE and Referer: http://10.0.1.92/OPEN.
那个371一开始没看懂是Referer中/OPEN的字符串位置:http://10.0.1.92/OPEN。该匹配项将状态翻转回 OPEN,直到 Referer 更改并产生观察到的行为。
我将 if 语句更改为包含 space,这样就只会匹配 GET /CLOSE 或 GET /OPEN,即
if (request.indexOf(" /CLOSE") != -1){ . . .
if (request.indexOf(" /OPEN") != -1){ . . .
并且它可以正常工作。所以,逻辑上没有任何问题,它正在做它应该做的事情 ;)。
感谢 JLH 的帮助。
我一直在自学 ESP8226 编程,特别是 ESP8226-12F。我有这个基于在线示例的脚本:
#include <ESP8266WiFi.h>
WiFiServer server(80); //Initialize the server on Port 80
void setup() {
WiFi.mode(WIFI_AP); //Our ESP8266-12E is an AccessPoint
WiFi.begin("***","***"); // Provide the (SSID, password);
Serial.begin(115200); //Start communication between the ESP8266-12E and the monitor window
IPAddress HTTPS_ServerIP= WiFi.localIP(); // Obtain the IP of the Server
Serial.print("Server IP is: "); // Print the IP to the monitor window
Serial.println(HTTPS_ServerIP);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
server.begin(); // Start the HTTP Server
}
void loop() {
String status;
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("Somebody has connected :)");
//Read what the browser has sent into a String class and print the request to the monitor
String request = client.readString();
Serial.println(request);
// Handle the Request
if (request.indexOf("/CLOSE") != -1) {
Serial.println(request.indexOf("/CLOSE"));
status = "CLOSED";
}
if (request.indexOf("/OPEN") != -1) {
Serial.println(request.indexOf("/OPEN"));
status = "OPEN";
}
Serial.println(status);
// The HTML
String s = "HTTP/1.1 200 OK";
s += "Content-Type: text/html\r\n\r\n";
s += "<!DOCTYPE html><html><head><meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'\"> <meta name=\"referrer\" content=\"no-referrer\" /></head><body>";
s += "<br><input type=\"button\" name=\"b1\" value=\"OPEN DOOR\" onclick=\"javascript:location.href='/OPEN'\">";
s += "<br><input type=\"button\" name=\"b2\" value=\"CLOSE DOOR\" onclick=\"javascript:location.href='/CLOSE'\">";
if(status == "OPEN") {
s+= "<br><br><p>OPEN</p>";
} else {
s+= "<br><br><p>CLOSED</p>";
}
s += "</body></html>\n";
client.flush(); //clear previous info in the stream
client.print(s); // Send the response to the client
delay(1);
Serial.println("Client disonnected");
您会看到初始 HTTP 响应创建了两个按钮:OPEN DOOR 和 CLOSE DOOR。
我遇到的问题是必须按两次关闭按钮才能使草图输出 "CLOSED"。
这是串行监视器的输出。
1: 第一次浏览到 http://10.0.1.92:
Somebody has connected :)
GET / HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Client disonnected
2: 按打开按钮 http://10.0.1.92/OPEN 显示 "OPEN"
Somebody has connected :)
GET /OPEN HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://10.0.1.92/
4 // This is value of request.indexOf("/CLOSE")
OPEN
Client disonnected
3: 按CLOSE http://10.0.1.92/CLOSE 仍然显示"OPEN"
Somebody has connected :)
GET /CLOSE HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://10.0.1.92/OPEN
4
371 // No idea where this comes from
OPEN
Client disonnected
4:第二次按CLOSE,显示"CLOSED":
Somebody has connected :)
GET /CLOSE HTTP/1.1
Host: 10.0.1.92
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://10.0.1.92/CLOSE
4
CLOSED
Client disonnected
为什么要按两次关闭按钮才能显示 "CLOSED"?这是逻辑问题,还是 HTTP 问题,还是两者的某种结合?
这是可疑的:
if(status == "OPEN"){
s+= "<br><br><p>"+status+"</p>";
} else {
s+= "<br><br><p>"+status+"</p>";
}
如果两个选项相同,if
语句是什么?
另外 Referer
显示了三个不同的值,而根据您的设计,一个人会期望两个值。我想知道你最初在哪里设置这个二进制状态机的状态?
编辑:
所以 OP 更新了源代码。
if(status == "OPEN") {
s+= "<br><br><p>OPEN</p>";
} else {
s+= "<br><br><p>CLOSED</p>";
}
对战:
if (request.indexOf("/CLOSE") != -1) {
Serial.println(request.indexOf("/CLOSE"));
status = "CLOSED";
}
if (request.indexOf("/OPEN") != -1) {
Serial.println(request.indexOf("/OPEN"));
status = "OPEN";
}
你现在看到它们在逻辑上有何不同了吗?
这可能意味着当状态机启动时,由于它没有打开,所以它在顶部块中关闭但在底部块中没有关闭。按下下一个按钮将其更改为打开,然后第二次将其更改为关闭?这可能是正在发生的事情吗?
问题是这些语句:
if (request.indexOf("/CLOSE") != -1){ . . .
if (request.indexOf("/OPEN") != -1){ . . .
如果您查看响应字符串,您会发现那些 if 语句与 GET /OPEN 或 GET /CLOSED 以及 Referer 相匹配:http://10.0.1.92/CLOSE and Referer: http://10.0.1.92/OPEN.
那个371一开始没看懂是Referer中/OPEN的字符串位置:http://10.0.1.92/OPEN。该匹配项将状态翻转回 OPEN,直到 Referer 更改并产生观察到的行为。
我将 if 语句更改为包含 space,这样就只会匹配 GET /CLOSE 或 GET /OPEN,即
if (request.indexOf(" /CLOSE") != -1){ . . .
if (request.indexOf(" /OPEN") != -1){ . . .
并且它可以正常工作。所以,逻辑上没有任何问题,它正在做它应该做的事情 ;)。
感谢 JLH 的帮助。