ESP8266 5000 миллисекунд задержки при отправке сообщения - PullRequest
0 голосов
/ 05 октября 2018

Мой проект состоит из двух коробок, в которых есть две кнопки - красная и желтая.Когда вы нажимаете желтый на сервере, сервер светится желтым светодиодом, затем, когда вы нажимаете желтый на клиенте, клиент горит желтым светодиодом, и желтая команда выигрывает (то же самое с красным, и вы можете повторно щелкнуть от желтого до красного перед победой).После выигрыша вам необходимо подключиться к веб-серверу на СЕРВЕРЕ (например, с телефона) и перезапустить игру через него.

Я использую два Wemos D1 mini pro (клоны с алиэкспресса), один из них - СЕРВЕР, один - этоКЛИЕНТ.СЕРВЕР работает в качестве точки доступа для КЛИЕНТА (и телефона или ПК для сброса).Я использую ESP8266WebServer.h для запуска webServer на порту 80 на сервере SERVER и ESP8266WiFi.h для запуска связи сервер на порту 8080. Я отправляю через сервер одинСлово, чтобы сообщить клиенту, какой цвет сейчас на СЕРВЕРЕ и наоборот.все работает нормально, пока что-то не подключится к webServer , тогда отправка сообщения через сервер иногда отстает ровно на 5000 мс, что, я думаю, является постоянным в библиотеке.И проблема сохраняется даже после отключения от 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");
}
...