I'm using this code to wait an answer finishing with a specific end marker (a cString not just a char) for a maximum amount of time. (ESPSEPRIAL
is whatever stream you are listening from, could be your SoftwareSerial port or if you are on a mega one of the Hardware Serial Port.)
// --------------------------------------
// waitForString wait max for duration ms whilst checking if endMarker string is received
// on the ESPSEPRIAL port returns a boolean stating if the marker was found
// --------------------------------------
boolean waitForString(const char * endMarker, unsigned long duration)
{
int localBufferSize = strlen(endMarker); // we won't need an \0 at the end
char localBuffer[localBufferSize];
int index = 0;
boolean endMarkerFound = false;
unsigned long currentTime;
memset(localBuffer, '\0', localBufferSize); // clear buffer
currentTime = millis();
while (millis() - currentTime <= duration) {
if (ESPSEPRIAL.available() > 0) {
if (index == localBufferSize) index = 0;
localBuffer[index] = (uint8_t) ESPSEPRIAL.read();
deepDebugMessage(localBuffer[index]);
endMarkerFound = true;
for (int i = 0; i < localBufferSize; i++) {
if (localBuffer[(index + 1 + i) % localBufferSize] != endMarker[i]) {
endMarkerFound = false;
break;
}
}
index++;
}
if (endMarkerFound) break;
}
return endMarkerFound;
}
the code uses a circular buffer to compare what is received over the ESPSEPRIAL line with what we expect. The full answer is ignored though, we only care to know if we got the endMarker message.
I use that to see if I get correctly an "OK\r\n"
from AT commands for example.
I define those functions:
// --------------------------------------
// espPrintlnATCommand sends an AT command by adding at the end a CR LF
// then it checks if an endMarker string is received on the ESP Serial port
// for max duration ms returns a boolean stating if the marker was found
// --------------------------------------
boolean espPrintlnATCommand(const char * command, const char * endMarker, unsigned long duration)
{
debugMessage(DOT_STR);
ESPSEPRIAL.println(command);
return waitForString(endMarker, duration);
}
for example I would do
const char * OK_STR = "OK\r\n";
....
// connect to my WiFi network and create the TCP server
if (!espPrintlnATCommand("AT+RESTORE", "ready", LONG_PAUSE)) dontGoFurther("RESTORE failed"); // reset
if (!espPrintlnATCommand("AT+CWMODE=1", OK_STR, SHORT_PAUSE)) dontGoFurther("CWMODE failed"); //Set the wireless mode to station
if (!espPrintlnATCommand("AT+CWQAP", OK_STR, SHORT_PAUSE)) dontGoFurther("CWQAP failed"); //disconnect - it shouldn't be but just to make sure
where LONG_PAUSE, SHORT_PAUSE are defined this way
#define SHORT_PAUSE (1000ul)
#define LONG_PAUSE (10000ul)
and I have a dontGoFurther() function that ends the program with an error message
// Comment out this line to remove all Debug information
#define debugFlag
#ifdef debugFlag
#define debugMessage(...) Serial.print(__VA_ARGS__)
#else
#define debugMessage(...) {}
#endif
// --------------------------------------
// this will lock your arduino, watchdog might reset
// --------------------------------------
void dontGoFurther(const char * errorMessage)
{
debugMessage(F("Can't continue: "));
debugMessage(errorMessage);
debugMessage(F("\n"));
while (1); // die here
}
hope this helps