ESP8266 - Как правильно написать обработку данных, пришедших с клиента

lennen
Offline
Зарегистрирован: 10.11.2015

Добрый день. У меня есть код, где я управляю светодиодной лентой через WiFi. Через браузер с ноутбука. Вначале я жду клиента, подключаю его к серверу, который находится на ESP8266. Затем обрабатываю с него данные и если они совпали с некоторыми командами - включаю разные цвета. Скетч после отработки запроса отключает клиента и подключает заново, как я понимаю. То есть в loop(действие происходит не по циклу, а ждет команду от клиента). Проблема в том, что я пробовал по всякому написать код. И ниже выкладываю один из вариантов.

Вообще, какая логика не оправдалась. Я думал, что если после проверки условия, что мы приняли команду, мы напишем while и будет проверять String request = client.readStringUntil('\r'); - мы отследим, когда пришли другие данные. Думал, что приходит пустая строка до тех пор, пока в браузере не нажмем еще кнопку, и мы по циклу можем сделать плавное изменение цвета от выкл до яркого желтого. В реале этот request выдает то, что я не совсем ожидал. Помогите, пожалуйста, разобраться, как правильно сделать? Прикладываю весь код. 

if (request.indexOf("/LED=FIRESHOW1") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;
Serial.println("Otrabotka: ");

for (int j = 0; j < 255; j++) {
  if (client.readStringUntil('\r').indexOf("/LED=FIRESHOW1") != -1) {
    pixels.clear(); // Set all pixel colors to 'off' 
    for(int i = 0; i < NUMPIXELS; i++){
      pixels.setPixelColor(i, pixels.Color(j, 0, j));
      j++;
      pixels.show();   // Send the updated pixel colors to the hardware.
    }
    delay(50);
  }
}
}

Весь код:

#include <ESP8266WiFi.h>

unsigned long timing; // Переменная для хранения точки отсчета
int j = 0;

const char* ssid = "MGTS_GPON_3DEC";//type your ssid
const char* password = "DA5RMHH3";//type your password

int ledPin = 2; // GPIO2 of ESP8266
WiFiServer server(80);//Service Port

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
#define PIN        4 // On Trinket or Gemma, suggest changing this to 1

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 15 // Popular NeoPixel ring size

// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)




Serial.begin(115200);
delay(10);

pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);

// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");

// Start the server
server.begin();
Serial.println("Server started");

// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}

void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}

// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
  delay(1);
}

// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();

// Match the request

int value = LOW;
if (request.indexOf("/LED=BLUE") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
  pixels.setPixelColor(i, pixels.Color(0, 150, 0));
}
pixels.show();   // Send the updated pixel colors to the hardware.
} 

if (request.indexOf("/LED=RED") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
  pixels.setPixelColor(i, pixels.Color(150, 0, 0));
}
pixels.show();   // Send the updated pixel colors to the hardware.
} 

if (request.indexOf("/LED=GREEN") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
pixels.setPixelColor(i, pixels.Color(0, 0, 150));
}
pixels.show();   // Send the updated pixel colors to the hardware.
}

if (request.indexOf("/LED=WHITE") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
pixels.setPixelColor(i, pixels.Color(150, 150, 150));
}
pixels.show();   // Send the updated pixel colors to the hardware.
} 

if (request.indexOf("/LED=PINK") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
pixels.setPixelColor(i, pixels.Color(255, 0, 255));
}
pixels.show();   // Send the updated pixel colors to the hardware.
}

if (request.indexOf("/LED=MAROON") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
pixels.setPixelColor(i, pixels.Color(128, 0, 0));
}
pixels.show();   // Send the updated pixel colors to the hardware.
}

if (request.indexOf("/LED=PURPLE") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
pixels.setPixelColor(i, pixels.Color(128, 50, 255));
}
pixels.show();   // Send the updated pixel colors to the hardware.
}

if (request.indexOf("/LED=DARK") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
pixels.setPixelColor(i, pixels.Color(128, 255, 0));
}
pixels.show();   // Send the updated pixel colors to the hardware.
}

if (request.indexOf("/LED=OFF") != -1){
digitalWrite(ledPin, LOW);
value = LOW;

pixels.clear(); // Set all pixel colors to 'off'
for(int i = 0; i < NUMPIXELS; i++){
pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
pixels.show();   // Send the updated pixel colors to the hardware.
}


if (request.indexOf("/LED=FIRESHOW1") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;
Serial.println("Otrabotka: ");

for (int j = 0; j < 255; j++) {
  if (client.readStringUntil('\r').indexOf("/LED=FIRESHOW1") != -1) {
    pixels.clear(); // Set all pixel colors to 'off' 
    for(int i = 0; i < NUMPIXELS; i++){
      pixels.setPixelColor(i, pixels.Color(j, 0, j));
      j++;
      pixels.show();   // Send the updated pixel colors to the hardware.
    }
    delay(50);
  }
}
}

//Set ledPin according to the request
//digitalWrite(ledPin, value);

// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); //  do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");

client.print("Led pin is now: ");

if(value == HIGH) {
client.print("On");  
} else {
client.print("Off");
}
client.println("<br><br>");
client.println("");

String message = "\
<input type=\"range\" min=\"0\" max=\"100\" step=\"1\" value=\"50\">\
\
<style>\
button {\ 
  width:120px;\ 
  height: 60px;\
  font-weight: 700;\
  color: white;\
  text-decoration: none;\
  padding: .8em 1em calc(.8em + 3px);\
  border-radius: 3px;\
  background: rgb(64,199,129);\
  box-shadow: 0 -3px rgb(53,167,110) inset;\
  transition: 0.2s;\
}\
</style>\
\
<table>\
<tr>\
<td><a href=\"/LED=RED\"><button onlick=\"return false;\">Red</button></a></td>\
<td><a href=\"/LED=GREEN\"><button onlick=\"return false;\">Green</button></a></td>\
<td><a href=\"/LED=BLUE\"><button onlick=\"return false;\">Blue</button></a></td>\
</tr>\
<tr>\
<td><a href=\"/LED=WHITE\"><button onlick=\"return false;\">White</button></a></td>\
<td><a href=\"/LED=PINK\"><button onlick=\"return false;\">Pink</button></a></td>\
<td><a href=\"/LED=MAROON\"><button onlick=\"return false;\">Maroon</button></a></td>\
</tr>\
<tr>\
<td><a href=\"/LED=PURPLE\"><button onlick=\"return false;\">Purple</button></a></td>\
<td><a href=\"/LED=DARK\"><button onlick=\"return false;\">Dark</button></a></td>\
<td><a href=\"/LED=OFF\"><button onlick=\"return false;\">Off</button></a></td>\
</tr>\
</table>\
<br/>\
<a href=\"/LED=FIRESHOW1\"><button onlick=\"return false;\">Fireshow1</button></a>\
";

client.println(message);

client.println("</html>");

delay(100);
Serial.println("Client disconnected");
Serial.println("");
}

 

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

А просто пример сервера для есп проблвали ?
 

b707
Offline
Зарегистрирован: 26.05.2017

у вас этот скетч не должен даже компилироваться, код начиная со строки 217 "висит в воздухе" - то есть не относится ни к одной процедуре или функции.

А что касается обработки запросов - ваша догадка верна, запрос обрабатывается один раз и дальше сервер отключается от клиента. Чтобы обновить данные - надо сформировать новый запрос, например на страничке ввести новые данные и снова нажать кнопку отправки. Сами данные обновлятся, например как вы думали в цикле while() - не будут.

Может вам почитать какую-нить популярную статью о протоколе HTTP?