There are, obviously, a great number of ways that this can be achieved. The simple brute force way would be to have a series of if
statements, looking for a sequence of eight consecutive 0
s and/or 1
s, and loop through the string containing the response.
Or you could loop through the response, using strcmp()
, similar to what is described here: how to do like a grep in a sketch?
However, a more intelligent method would be to use pattern matching and regular expressions.
From New regular expression library released, Nick has provided a Regexp library. It uses Lua for the expression syntax, see string.find, for more details.
I am still playing with this code, but your sketch would need something like this:
#include <Regexp.h>
void setup ()
{
Serial.begin (115200);
Serial.println ();
unsigned int index = 0;
char buf [100];
MatchState ms;
ms.Target ("HTTP/1.1 200 OK\
Date: Sun, 02 Jul 2017 07:53:29 GMT\
Server: Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1\
X-Powered-By: PHP/5.3.1\
Content-Length: 13\
Content-Type: text/html\
\
\
<10110110>"); // what to search
while (true){
char result = ms.Match ("^<([01][01][01][01][01][01][01][01])", 0); // look for an eight bit binary digit
if (result == REGEXP_MATCHED)
{
Serial.println ("-----");
Serial.print ("Matched on: ");
Serial.println (ms.GetMatch (buf));
Serial.println ("Captures:");
for (int j = 0; j < ms.level; j++)
Serial.println (ms.GetCapture (buf, j));
// move past matching string
index = ms.MatchStart + ms.MatchLength;
} // end of match
else
break; // no match or regexp error
} // end of while
} // end of setup
void loop () {}
This code assumes that you are looking for a line beginning with <
and captures an eight digit binary thereafter - as determined by the expression within the inner ()
, in the line:
char result = ms.Match ("^<([01][01][01][01][01][01][01][01])", 0); // look for an eight bit binary digit
So, it should output:
-----
Matched on: <10110110
Captures: 10110110
-----
Obviously, instead of just outputting the captured binary digits to the serial monitor, you need to save them for your relay control.
For neatness, you could replace
ms.Target ("HTTP/1.1 200 OK\
Date: Sun, 02 Jul 2017 07:53:29 GMT\
Server: Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1\
X-Powered-By: PHP/5.3.1\
Content-Length: 13\
Content-Type: text/html\
\
\
<10110110>"); // what to search
with
char * str = "HTTP/1.1 200 OK\
Date: Sun, 02 Jul 2017 07:53:29 GMT\
Server: Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1\
X-Powered-By: PHP/5.3.1\
Content-Length: 13\
Content-Type: text/html\
\
\
<10110110>";
ms.Target (str);
Note the use of the backslashes at the ends of the lines. I've included them here, in order to get the test sketch to compile. You probably will not need them as you would be receiving the response from the server, and not providing an example string for testing.
Here is a working version, along with multiple test strings (input_str
) and example match strings (match_str
):
#include <Regexp.h>
void setup ()
{
Serial.begin (9600);
// Serial.begin (115200);
Serial.println ();
unsigned int index = 0;
char buf [100];
// Simple test pair
// char * input_str = "RGB:123";
// char * match_str = "(%a)";
// Simulated MySQL responses
// Most basic
// char * input_str = "<10110110>";
// Over two lines
// char * input_str = "http\\n<10110110>";
// Full response
char * input_str = "HTTP/1.1 200 OK\
Date: Sun, 02 Jul 2017 07:53:29 GMT\
Server: Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1\
X-Powered-By: PHP/5.3.1\
Content-Length: 13\
Content-Type: text/html\
\
\
<10110110>";
// Full response with newlines
// char * input_str = "HTTP/1.1 200 OK\\n\
Date: Sun, 02 Jul 2017 07:53:29 GMT\\n\
Server: Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1\\n\
X-Powered-By: PHP/5.3.1\\n\
Content-Length: 13\\n\
Content-Type: text/html\\n\
\\n\
\\n\
<10110110>";
// Shorter version of full MySQL response with newlines
// char * input_str = "Content-Type: text/html\\n\
\\n\
\\n\
<10110110>";
// Shorter version of full MySQL response with newlines with no preceeding spaces
// char * input_str = "Content-Type: text/html\\n\
\\n\
\\n\
<10110110>";
// Match strings for MySQL response, containing an eight bit binary number
// Match at beginning of line
// char * match_str = "^<([01][01][01][01][01][01][01][01])";
// Match at beginning of line with multiple newline characters
char * match_str = "[\n]*<([01][01][01][01][01][01][01][01])";
// Match at beginning of line with zero or one newline characters
// char * match_str = "[\n]?<([01][01][01][01][01][01][01][01])";
// Match at anywhere
// char * match_str = "<([01][01][01][01][01][01][01][01])";
MatchState ms;
while (true){
char result = ms.Match (match_str, 0);
if (result == REGEXP_MATCHED)
{
Serial.println ("-----");
Serial.print ("Matched on: ");
Serial.println (ms.GetMatch (buf));
Serial.println ("Captures:");
for (int j = 0; j < ms.level; j++)
Serial.println (ms.GetCapture (buf, j));
// move past matching string
index = ms.MatchStart + ms.MatchLength;
} // end of match
else
break; // no match or regexp error
} // end of while
} // end of setup
void loop () {}
For the match_str
line,
char * match_str = "[\n]*<([01][01][01][01][01][01][01][01])";
you may or may not need the caret (^
) to match at the start of the line, and the [\n]*
or [\n]?
. See which combination works for you.