1

Basically I created a web page to control 4 channel relay, then I made an HTTP get request from that page and got the following response:

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

Now I want to store Relay1 status (which is 1 here) in a variable, also all other Relays in order to control them high or low Note : # is supposed to be the separator and here is my code:

    #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");
}
  }


}

Any suggestions ?

1
  • 1
    why do you send it as html like text? send 1001
    – Juraj
    Apr 7, 2018 at 10:34

1 Answer 1

1

First of all, I would avoid using the String class, because of the memory fragmentation issues that come with it. The most obvious solution is probably to store the result in a character array, then parse the array, with strstr() or sscanf(), to extract the values you want. However, this requires storing the whole response in RAM, which is expensive. A better option is to parse the string as it comes, character by character, using a kind of finite state machine.

Here is how I would do it. First, I assume you know what you want to do with these values. Since I don't, I will instead use this dummy function to just print the values out to the serial port:

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

You will have to replace this with whatever is appropriate for your application.

Then here is the parser:

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;
}

You just feed it one character at a time, with something like:

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

Feeding the parser with your response example gives the following on the serial port:

parsed: relay 1: 1
parsed: relay 2: 0
parsed: relay 3: 0
parsed: relay 4: 1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.