我的项目大约有两个框,在框上有两个红色和黄色按钮。当您在服务器上按黄色时,服务器会点亮黄色指示灯,然后在客户端上按黄色时,客户端会点亮黄色指示灯,黄色团队获胜(与红色相同,您可以在获胜之前将黄色重新单击为红色)。获胜后,您需要连接到SERVER上的Web服务器(例如通过电话),然后通过它重新启动游戏。
我正在使用两个Wemos D1 mini pro(来自aliexpress的克隆),其中之一是SERVER,一个是CLIENT。 SERVER用作CLIENT(以及要重置的电话或PC)的访问点。我使用ESP8266WebServer.h在SERVER端口80上运行 webServer ,并使用ESP8266WiFi.h在8080端口上运行通讯服务器。我通过服务器发送一个单词让服务器知道客户端现在是哪种颜色,反之亦然。一切正常,直到某些东西连接到 webServer ,然后通过服务器发送消息时有时会滞后5000ms,我认为这在库中是恒定的。与 webServer 断开连接后,问题仍然存在。这种滞后不能使程序的其他部分正常工作,因此发生滞后时我无法检查按钮状态。
我在库中搜索了很多已更改的方法来发送消息,甚至更改了整个库,但问题仍然出现,我觉得我的代码部分不好。
有人可以帮我解决这个5秒的问题吗?
服务器代码:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <TimeLib.h>
#include "indexDominator.h"
ESP8266WebServer webServer(80);
WiFiServer server(8080);
IPAddress IP(192, 168, 4, 1);
IPAddress mask = (255, 255, 255, 0);
#define YELOW_LED D7
#define RED_LED D8
#define YELLOW_BUTTON D5
#define RED_BUTTON D6
#define STRIP_PIN D2
#define BUZZER_PIN D1
bool yellow = false; //actual color at server
bool red = false; //actual color at server
// TIMERS
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long timeY = 0; // the last time the output pin was toggled
int readingY; // the current reading from the input pin
long timeR = 0; // the last time the output pin was toggled
int readingR; // the current reading from the input pin
long debounce = 200; // the debounce time, increase if the output flickers
int ledState = LOW; // ledState used to set the LED
int buzzerState = LOW; // buzzerState used to set the buzzer
unsigned long previousMillisBuzzer = 0; // will store last time Buzzer was updated
unsigned long previousMillisLed = 0; // will store last time Led was updated
const long intervalBuzzer = 5000; // interval at which to blink (milliseconds)
const long intervalLed = 500;
String requestC = "";
String message = "none";
bool var_win = false;
bool var_reset = false;
int redWin = 0;
int yellowWin = 0;
//debug vars
int warning = 0;
int lastWarning = 0;
void setup() {
pinMode(YELOW_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_BUTTON, INPUT);
pinMode(RED_BUTTON, INPUT);
pinMode(BUILTIN_LED, OUTPUT);
pinMode(STRIP_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUILTIN_LED, LOW); //turn on BUILTIN_LED to show that board is powered up
Serial.begin(74880);
WiFi.mode(WIFI_OFF);//workaround
WiFi.mode(WIFI_AP);
WiFi.softAP("DOMINATOR_SERVER", "password", 11); //third parameter 3 is channel => WiFi.softAP(ssid, password, channel, hidden)
WiFi.softAPConfig(IP, IP, mask);
webServer.on("/", handleRoot);
webServer.on("/resetGame", handleReset);
webServer.on("/readTime", handleTime);
webServer.on("/readRed", handleRed);
webServer.on("/readYellow", handleYellow);
webServer.on("/readColorClient", handleColorClient);
webServer.on("/readColorServer", handleColorServer);
webServer.begin();
server.begin();
Serial.println();
Serial.println("Wemos server");
Serial.println("Server started.");
Serial.print("IP: "); Serial.println(WiFi.softAPIP());
Serial.print("MAC:"); Serial.println(WiFi.softAPmacAddress());
}
void loop() {
//CLIENT CONNECTION
WiFiClient clientC = server.available();
clientC.setTimeout(0); //because of 1 sec delay in readStringUntil()
clientC.setNoDelay(true); //maybe useless ?
if (!var_win) {
// BUTTONS CHECK
readingY = digitalRead(YELLOW_BUTTON);
if (readingY == HIGH && millis() - timeY > debounce) {
turnONyellow();
if (yellow == false) {
message = "YELLOW";
}
yellow = true;
red = false;
timeY = millis();
}
readingR = digitalRead(RED_BUTTON);
if (readingR == HIGH && millis() - timeR > debounce) {
turnONred();
if (red == false) {
message = "RED";
}
yellow = false;
red = true;
timeR = millis();
}
}
if (var_reset) {
message = "reset";
}
Serial.println("##############################1##############################");
Serial.println("Sending message: " + message);
int timer = millis();
clientC.print(message);
Serial.print("Sending tooks: ");
Serial.println(millis() - timer, DEC);
if (millis() - timer > 3000) {
warning++;
Serial.println(" ##############################11##############################");
Serial.println(" ### ###");
printf(" ### WARNING ID:%d TimesinceLast:%d sec ###", warning, (millis() - lastWarning) / 1000);
Serial.println();
Serial.println(" ### ###");
Serial.println(" ##############################11##############################");
lastWarning = millis();
}
Serial.println("##############################11##############################");
if (var_reset) {
message = "none";
var_win = false;
yellow = false;
red = false;
var_reset = false;
}
Serial.println("##############################2##############################");
requestC = clientC.readStringUntil('\r');
if (requestC.length() > 0) {
Serial.println("From the client: " + requestC);
if (requestC == message && message != "none") {
if (message == "RED" && !var_win) {
redWin++;
}
if (message == "YELLOW" && !var_win) {
yellowWin++;
}
var_win = true;
}
}
Serial.println("##############################3##############################");
if (var_win) {
win();
}
Serial.println("##############################4##############################");
webServer.handleClient(); //handles whole website
delay(1);
Serial.println("##############################5##############################");
clientC.stop();
}
//##########METHODS##########
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
String s = MAIN_page; //Read HTML contents
webServer.send(200, "text/html", s); //Send web page
}
void handleReset() {
String t_state = webServer.arg("ResetState");
if (t_state == "1" /*&& var_win*/)
{
Serial.println("Restartovanie hry prebieha...");
turnOFFleds();
var_reset = true;
}
}
void handleRed() {
webServer.send(200, "text/plane", String(redWin));
}
void handleYellow() {
webServer.send(200, "text/plane", String(yellowWin));
}
void handleColorClient() {
String colorClient = "žiadna";
if (requestC == "YELLOW") {
colorClient = "žltá";
} else if (requestC == "RED") {
colorClient = "červená";
}
webServer.send(200, "text/plane", colorClient);
}
void handleColorServer() {
String colorServer = "žiadna";
if (message == "YELLOW") {
colorServer = "žltá";
} else if (message == "RED") {
colorServer = "červená";
}
webServer.send(200, "text/plane", colorServer);
}
void handleTime() {
//Serial.println(getTime());
webServer.send(200, "text/plane", getTime());
}
String getTime() {
String Time = ""; //uppercase because time is from some library
Time += hour();
Time += returnDigits(minute());
Time += returnDigits(second());
return Time;
}
String returnDigits(int number) {
// utility function for digital clock display: prints preceding colon and leading 0
String digits = "";
digits += ":";
if (number < 10)
digits += "0";
digits += number;
return digits;
}
//##########LED CONTROL##########
void turnONyellow() {
Serial.println("YELLOW on");
digitalWrite(RED_LED, LOW);
digitalWrite(YELOW_LED, HIGH);
//TODO led strip
}
void turnONred() {
Serial.println("RED on");
digitalWrite(RED_LED, HIGH);
digitalWrite(YELOW_LED, LOW);
//TODO led strip
}
void turnOFFleds() {
ledState == LOW; //used for blinking
digitalWrite(RED_LED, LOW);
digitalWrite(YELOW_LED, LOW);
buzzerState = LOW; //used for beeping
digitalWrite(BUZZER_PIN, LOW); //used for beeping
Serial.println("All leds are off");
//TODO led strip
}
void win() { // what shows if on both devices is same color
Serial.println("WIN");
unsigned long currentMillis = millis();
if (currentMillis - previousMillisBuzzer >= intervalBuzzer) {
previousMillisBuzzer = currentMillis; // save the last time you beeped the buzzer
// if buzzer is off turn it on and vice-versa:
if (buzzerState == LOW) {
buzzerState = HIGH;
} else {
buzzerState = LOW;
}
digitalWrite(BUZZER_PIN, buzzerState);
}
//button led blink
if (currentMillis - previousMillisLed >= intervalLed) {
previousMillisLed = currentMillis; // save the last time you beeped the buzzer
// if buzzer is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
if (yellow) {
digitalWrite(YELOW_LED, ledState);
} else {
digitalWrite(RED_LED, ledState);
}
}
Serial.println("END WIN");
//TODO led strip blink
//TODO web server button show/hide
}
网页的服务器索引:
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
#demo {text-align: center;}
#RedWin {text-color:red;}
#YellowWin {text-color:yellow;}
#resetButt {background-color: red;
border-radius: 5px;
font-weight: bold;
border-color: black;
padding: 20;}
#roundRed {border: 2px solid red;
border-radius: 5px;
padding: 5px 5px 5px 5px;
display: inline-block;
margin: 5px;}
#roundYellow {border: 2px solid yellow;
border-radius: 5px;
padding: 5px 5px 5px 5px;
display: inline-block;
margin: 5px;}
#roundBlack {border: 2px solid black;
border-radius: 5px;
padding: 5px 5px 5px 5px;
display: inline-block;
margin: 5px;}
div {
//margin: 25px;
}
</style>
</head>
<body>
<div id="demo">
<h1>Dominator</h1>
<p class="time">Čas: <span id="Time">0</span></p><br>
<div>
<p id="roundRed">Počet výhier červený : <span id="RedWin">0</span><br> Čas červený : <span id="RedTime">0</span></p>
</div>
<div>
<p id="roundYellow">Počet výhier žltý : <span id="YellowWin">0</span><br> Čas žltý : <span id="RedTime">0</span></p><br>
</div>
<div>
<p id="roundBlack">Farba SERVER: <span id="ServerColor">NA</span><br>Farba CLIENT: <span id="ClientColor">NA</span></p><br>
</div>
<div>
<button type="button" id="resetButt" onclick="sendData(1)">Reštartovať hru</button><br>
</div>
</div>
<script>
function sendData(state) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("resetGame").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "resetGame?ResetState="+state, true);
xhttp.send();
}
setInterval(function() {
// Call a function repetatively with 1 Second interval
getData();
}, 2000); //1000mSeconds update rate
function getData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("RedWin").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "readRed", true);
xhttp.send();
var xhttp1 = new XMLHttpRequest();
xhttp1.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("YellowWin").innerHTML =
this.responseText;
}
};
xhttp1.open("GET", "readYellow", true);
xhttp1.send();
var xhttp2= new XMLHttpRequest();
xhttp2.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("Time").innerHTML =
this.responseText;
}
};
xhttp2.open("GET", "readTime", true);
xhttp2.send();
//ServerColor
var xhttp3= new XMLHttpRequest();
xhttp3.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("ServerColor").innerHTML =
this.responseText;
}
};
xhttp3.open("GET", "readColorServer", true);
xhttp3.send();
//ClientColor
var xhttp4= new XMLHttpRequest();
xhttp4.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("ClientColor").innerHTML =
this.responseText;
}
};
xhttp4.open("GET", "readColorClient", true);
xhttp4.send();
}
</script>
</body>
</html>
)=====";
客户代码:
#include <ESP8266WiFi.h>
WiFiServer server(8080);
#define YELOW_LED D7
#define RED_LED D8
#define YELLOW_BUTTON D5
#define RED_BUTTON D6
#define STRIP_PIN D2
#define BUZZER_PIN D1
bool yellow = false;
bool red = false;
// TIMERS
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long timeY = 0; // the last time the output pin was toggled
int readingY; // the current reading from the input pin
long timeR = 0; // the last time the output pin was toggled
int readingR; // the current reading from the input pin
long debounce = 200; // the debounce time, increase if the output flickers
int ledState = LOW; // ledState used to set the LED
int buzzerState = LOW; // buzzerState used to set the buzzer
unsigned long previousMillisBuzzer = 0; // will store last time Buzzer was updated
unsigned long previousMillisLed = 0; // will store last time Led was updated
const long intervalBuzzer = 5000; // interval at which to blink (milliseconds)
const long intervalLed = 500;
String requestC = "";
String color = "none";
const char* _SSID = "DOMINATOR_SERVER"; // previously [const char* SSID = "xxxxxx";] seems SSID now is an reserved constant, so I added "_"
const char* _PASS = "password";//not sure but seems similar to anterior I added "_" to avoid conflict
bool var_win = false;
//debug vars
int warning = 0;
int lastWarning = 0;
WiFiClient client;
void setup() {
pinMode(YELOW_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_BUTTON, INPUT);
pinMode(RED_BUTTON, INPUT);
pinMode(BUILTIN_LED, OUTPUT);
pinMode(STRIP_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUILTIN_LED, LOW); //turn on BUILTIN_LED to show that board is powered up
Serial.begin(74880);
Serial.print("Connecting to server.");
WiFi.mode(WIFI_STA);
WiFi.begin(_SSID, _PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
//client.connect(WiFi.gatewayIP(), 8080);
client.connect("192.168.4.1", 8080);
Serial.println("Connected to server.");
server.begin();
Serial.println();
Serial.println("Wemos client");
Serial.println("Server started.");
Serial.print("LocalIP: "); Serial.println(WiFi.localIP());
Serial.println("MAC: " + WiFi.macAddress());
Serial.print("Gateway: "); Serial.println(WiFi.gatewayIP());
Serial.print("AP MAC: "); Serial.println(WiFi.BSSIDstr());
}
void loop() {
client.setTimeout(0); //becouse of 1 sec delay in readStringUntil()
Serial.println("##############################4##############################");
//client.connect(WiFi.gatewayIP(), 8080); //maybe useless every loop?
client.connect("192.168.4.1", 8080);
Serial.println("##############################5##############################");
client.setNoDelay(true);//maybe useless ?
//CONNECTION TO SERVER AFTER DISCONNECT
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Reconnecting to server.");
}
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
client.connect(WiFi.gatewayIP(), 8080);
Serial.println("Connected.");
Serial.print("LocalIP: "); Serial.println(WiFi.localIP());
}
}
//CLIENT CONNECTION
if (!var_win) {
// BUTTONS CHECK
readingY = digitalRead(YELLOW_BUTTON);
if (readingY == HIGH && millis() - timeY > debounce) {
turnONyellow();
if (yellow == false) { // shows just change of state of buttons good for web output
Serial.println("YELLOW");
color = "YELLOW";
}
yellow = true;
red = false;
timeY = millis();
}
readingR = digitalRead(RED_BUTTON);
if (readingR == HIGH && millis() - timeR > debounce) {
turnONred();
if (red == false) {
Serial.println("RED"); // shows just change of state of buttons good for web output
color = "RED";
}
yellow = false;
red = true;
timeR = millis();
}
}
//client.print(color);
//test
Serial.println("##############################1##############################");
Serial.println("Sending message: " + color);
int timer = millis();
client.print(color);
Serial.print("Sending tooks: ");
Serial.println(millis() - timer, DEC);
if (millis() - timer > 4000) {
warning++;
Serial.println(" ##############################11##############################");
Serial.println(" ### ###");
printf(" ### WARNING ID:%d TimesinceLast:%d sec ###", warning, (millis() - lastWarning) / 1000);
Serial.println();
Serial.println(" ### ###");
Serial.println(" ##############################11##############################");
lastWarning = millis();
}
Serial.println("##############################2##############################");
//end test
String request = client.readStringUntil('\r');
//Serial.println("********************************");
if (request.length() > 0) {
Serial.println("From the server: " + request);
if (request == color && color != "none") {
var_win = true;
}
if (request == "reset") {
handleReset();
}
}
if (var_win == true) {
win();
}
Serial.println("##############################3##############################");
client.stop() ;
delay(100);
}
//##########METHODS##########
void turnONyellow() {
digitalWrite(RED_LED, LOW);
digitalWrite(YELOW_LED, HIGH);
//TODO led strip
}
void turnONred() {
digitalWrite(RED_LED, HIGH);
digitalWrite(YELOW_LED, LOW);
//TODO led strip
}
void turnOFFleds() {
ledState == LOW; //used for blinking
digitalWrite(RED_LED, LOW);
digitalWrite(YELOW_LED, LOW);
buzzerState = LOW; //used for beeping
digitalWrite(BUZZER_PIN, LOW); //used for beeping
Serial.println("All leds are off");
//TODO led strip
}
void handleReset() {
turnOFFleds();
var_win = false;
color = "none";
yellow = false;
red = false;
}
void win() { // what shows if on both devices is one color
Serial.println("WIN");
unsigned long currentMillis = millis();
if (currentMillis - previousMillisBuzzer >= intervalBuzzer) {
previousMillisBuzzer = currentMillis; // save the last time you beeped the buzzer
// if buzzer is off turn it on and vice-versa:
if (buzzerState == LOW) {
buzzerState = HIGH;
} else {
buzzerState = LOW;
}
digitalWrite(BUZZER_PIN, buzzerState);
}
//button led blink
if (currentMillis - previousMillisLed >= intervalLed) {
previousMillisLed = currentMillis; // save the last time you beeped the buzzer
// if buzzer is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
if (yellow) {
digitalWrite(YELOW_LED, ledState);
} else {
digitalWrite(RED_LED, ledState);
}
}
Serial.println("END WIN");
}