Анализ HTTP-ответа на извлечение значений

В основном я создал веб-страницу для управления 4-канальным реле, затем я сделал запрос HTTP-запроса с этой страницы и получил следующий ответ:

Linked

T+CIPSEND=4,50

> GET /ard/sensor.html HTTP/1.1
Host: localho
SEND OK

+IPD,4,351:HTTP/1.1 200 OK
Date: Sat, 07 Apr 2018 01:22:58 GMT
Server: Apache/2.4.9 (Win32) PHP/5.5.12
Last-Modified: Sat, 07 Apr 2018 01:17:13 GMT
ETag: "72-56937eec1c277"
Accept-Ranges: bytes
Content-Length: 114
Content-Type: text/html

<p> Relay1 = 1#  </p> </br>
<p> Relay2 = 0#  </p> </br>
<p> Relay3 = 0#  </p> </br>
<p> Relay4 = 1#  </p> </br>
OK

OK
Unlink

Теперь я хочу сохранить статус Relay1 (который здесь 1) в переменной, а также все другие реле, чтобы контролировать их с высокой или низкой Примечание: # должен быть разделителем и вот мой код:

    #include <SoftwareSerial.h>

const int LED_PIN = 13;

String ssid = "ABC";
String password = "a14102016a";
const byte rxPin = 6;
const byte txPin = 7;

SoftwareSerial ESP8266 (rxPin, txPin);

unsigned long lastTimeMillis = 0;

void setup() {

  Serial.begin(9600);
  ESP8266.begin(9600);
  reset();
  connectWifi();
  delay(2000);
}


//reset the esp8266 module

void reset() {

  ESP8266.println("AT+RST");
  ESP8266.println("AT+CIOBAUD=9600");
  delay(1000);

  if (ESP8266.find("OK") ) Serial.println("Module Reset");

}


//connect to your wifi network
void connectWifi() {

  String cmd = "AT+CWJAP=\"" + ssid + "\",\"" + password + "\"";
  ESP8266.println(cmd);

  delay(4000);

  if (ESP8266.find("OK")) {

    Serial.println("Connected!");

  }

  else {

    connectWifi();

    Serial.println("connect to wifi");
  }

}

void printResponse() {
  while (ESP8266.available()) {
    Serial.println(ESP8266.readStringUntil('\n'));
  }
}

void loop() {

  if (millis() - lastTimeMillis > 30000) {
    lastTimeMillis = millis();

    ESP8266.println("AT+CIPMUX=1");
    delay(1000);
    printResponse();

    ESP8266.println("AT+CIPSTART=4,\"TCP\",\"192.168.1.161\",80");
    delay(1000);
    printResponse();

    String cmd = "GET /ard/sensor.html HTTP/1.1\r\nHost: localhost";
    ESP8266.println("AT+CIPSEND=4," + String(cmd.length() + 4));
    delay(1000);

    ESP8266.println(cmd);
    delay(1000);
    ESP8266.println("");    
  }
  if (ESP8266.available()) {
    Serial.write(ESP8266.read());

Byte R[ ] = ESP8266.read () ;
Serial write (R[ ]);

//    if (readString.indexOf("Relay1=1">0)) 
{
    Serial.write("found");
}
  }


}

Любые предложения?

1 голос | спросил ali_m 7 AMpSat, 07 Apr 2018 04:41:02 +030041Saturday 2018, 04:41:02

1 ответ


1

Прежде всего, я бы не стал использовать класс String, из-за проблемы с фрагментацией памяти, которые приходят с ней. Наиболее очевидное решение вероятно, сохранить результат в массиве символов, а затем проанализировать массив, с помощью strstr() или sscanf(), чтобы извлеките нужные значения. Однако для этого требуется хранить весь ответ в ОЗУ, который дорого. Лучшим вариантом является синтаксический анализ строки, как это происходит, символ по характеру, используя своего рода конечный автомат.

Вот как я это сделаю. Во-первых, я полагаю, вы знаете, что вы хотите сделать с этими значениями. Поскольку я этого не делаю, вместо этого я использую эту фиктивную функцию просто распечатать значения на последовательном порту:

 static void parse_relay_callback(uint8_t index, uint8_t value)
{
    Serial.print("parsed: relay ");
    Serial.print(index);
    Serial.print(": ");
    Serial.println(value);
}

Вам придется заменить это на все, что подходит для вашего приложение.

Тогда вот синтаксический анализатор:

 static void parse_relay(char c)
{
    static const char templ[] = "RelayI = V#"; // I: index, V: value
    static uint8_t pos, index, value;
    char expected = templ[pos++];
    if (expected == 'I' && c >= '0' && c <= '4')
        index = c - '0';
    else if (expected == 'V' && (c == '0' || c == '1'))
        value = c - '0';
    else if (expected == '#' && c == '#')
        parse_relay_callback(index, value);
    else if (c != expected)
        pos = 0;
}

Вы просто кормите его одним персонажем за раз, с чем-то вроде:

 while (ESP8266.available())
    parse_relay(ESP8266.read());

Подача синтаксического анализатора с помощью вашего примера ответа дает следующее последовательный порт:

 parsed: relay 1: 1
parsed: relay 2: 0
parsed: relay 3: 0
parsed: relay 4: 1
ответил Edgar Bonet 7 PMpSat, 07 Apr 2018 12:45:48 +030045Saturday 2018, 12:45:48

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132