ESP8266 - Как правильно написать обработку данных, пришедших с клиента
- Войдите на сайт для отправки комментариев
Добрый день. У меня есть код, где я управляю светодиодной лентой через 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("");
}
А просто пример сервера для есп проблвали ?
у вас этот скетч не должен даже компилироваться, код начиная со строки 217 "висит в воздухе" - то есть не относится ни к одной процедуре или функции.
А что касается обработки запросов - ваша догадка верна, запрос обрабатывается один раз и дальше сервер отключается от клиента. Чтобы обновить данные - надо сформировать новый запрос, например на страничке ввести новые данные и снова нажать кнопку отправки. Сами данные обновлятся, например как вы думали в цикле while() - не будут.
Может вам почитать какую-нить популярную статью о протоколе HTTP?