Checking for multiple escape characters

I’ve wrote a program that sends commands to my ESP8266 Wi-Fi chip.

I use a function called sendData(String command, const int timeout, boolean debug)

command - The command that is going to be sent to the Wi-Fi chip
time out - The time it will wait in a loop checking for a response
debug - If to print debug commands

Once a command is sent using this function its send via serial to the chip and then a response is collected in responseBuffer.

The problem is that I use a time out for all commands which means if I send a command with a time out of 10 seconds I must wait until the 10 seconds is over rather when the response from the Wi-Fi chip is complete.

The responses I get are “ready” and “OK” rather then a single character. How can I check efficiently that the last few characters of the responseBuffer are equal to “ready” and “OK”?

I’m also experiencing output from the chip of excess of 1000 characters however when I change responseBuffer to 1000+ characters it doesn’t seem to store anything and the program seems to freeze, how would I overcome this? what are the contestants of the Arduino uno (Atmega328) ?

#include <SoftwareSerial.h>
 
#define DEBUG true
 
SoftwareSerial esp8266(2,3);
                             
char responseBuffer[800];

void setup()
{
  
  Serial.begin(9600);
    
  esp8266.begin(9600); 
  
  sendData("AT+RST\r\n",2000,DEBUG);
  sendData("AT+CWMODE=3\r\n",2000,DEBUG);
  sendData("AT+CWJAP=\"SSID\",\"PASSWORD\"\r\n",10000,DEBUG);
  
  sendData("AT+CIPSTART=\"TCP\",\"api.noteu.co.uk\",80\r\n",2000,DEBUG); 
  sendData("AT+CIPSEND=84\r\n",2000,DEBUG); 
  sendData("GET http://api.noteu.co.uk/v1/poll/get/?serial_number=A000&secret=secret&time=0 \r\n\r\n\r\n",10000,DEBUG); 
 
}
 
void loop()
{
  
}
 
void sendData(String command, const int timeout, boolean debug)
{
    // Init array variables
    int ndx = 0;
    char rc = (char)0;
   
    // Clear array
    memset(responseBuffer, 0, sizeof(responseBuffer));
   
   Serial.println("Command : " + command);
   
    // Send command to module
    esp8266.print(command);
    
    // Record current time
    long int time = millis();
     
    // Timeout
    while(millis() - time < timeout)
    {
      
      while(esp8266.available() > 0)
      {
        
        rc = esp8266.read();
        
        responseBuffer[ndx] = rc;
	ndx++;

      }  
      
    }
    
    if(debug)
    {
      
      Serial.println(responseBuffer);
      
    }
    
}

I appreciate any help, thank you

The responses I get are "ready" and "OK" rather then a single character. How can I check efficiently that the last few characters of the responseBuffer are equal to "ready" and "OK"?

If the array is properly NULL terminated at all times, you can use strlen() to get the length of the string. Then, you can use strcmp() to compare the string (or portion of the string starting at some position) to known values.

int len = strlen(responseBuffer);
if(strcmp(responseBuffer[len-5], "ready") == 0)
{
   // string ends in ready
}

what are the contestants of the Arduino uno

Contestants? The UNO has 2048 bytes of SRAM. All arrays, string literals, and variables need to fit in that space.

You can keep string literals out by using the F() macro.

sendData(F("AT+RST\r\n"),2000,DEBUG);
Of course, this will require a change to the sendData() function.

And, quit using Strings. They waste memory.

You could be far more efficient with a different approach to the problem. What you are doing is suited to PC's that have lots of memory and cycles to waste.

The links below are especially good if you want the why as well as the how fully explained.
That way you don't just see some code and go off modding what you don't really get.

The not waiting for response while doing nothing is a first step in changing that approach.
Learn to not block!

Next step is to learn finite state machines and lose the buffers.

What you want will take a good bit of real work especially if you're trying to learn as you go.

I really mean the work part. Examples will show 1 letter codes only, they are a good start point. To recognize match words in an array takes more but it's nothing like rocket science, just serious programming.

I did it both ways in the 80's and found that buffering and text manipulation takes more code and memory to do the same thing slower than using state machines, and that was on the same PCs.

When I recently got into microcontrollers, I recognized that the small environment completely favors event driven code and state machines, which is no duh considering what MCU's are for.

If you want to try this and take the time to learn those basics, I'll help with getting it to recognize character sequences (aka words like OK and Ready and many others) stored in flash (program memory) and to print them.

The thing about serial data, it sends and arrives One Char At A Time. It does not have to be buffered at all except for unique sequences you want to save and use.

jacktrow1:
I've wrote a program that sends commands to my ESP8266 Wi-Fi chip.

I can't see the difference between what you are asking here, and the potential solutions to it and what is in your other Thread ?

IMHO it would be much simpler to keep all this stuff in one Thread.

...R

PaulS:
If the array is properly NULL terminated at all times, you can use strlen() to get the length of the string. Then, you can use strcmp() to compare the string (or portion of the string starting at some position) to known values.

Thanks for your response!

However I seem to be getting a complier error while implementing strcmp()

// Timeout
    while((millis() - time < timeout))
    {
      
      while(esp8266.available() > 0)
      {
        
        rc = esp8266.read();
        
        responseBuffer[ndx] = rc;
	ndx++;

        newData = true;

      }
      
      if(newData) {
      
        responseBuffer[ndx] = '\0';
        
        int len = strlen(responseBuffer);
        
        Serial.println("New Data! " + len);
        
        if(strcmp(responseBuffer[len-5], "ready") == 0) {
        
          Serial.println("Ends in ready!");
          
        }      
        
      }
      
    }

Error :

noteuv2.ino: In function 'void sendData(String, int, boolean)':
noteuv2:74: error: invalid conversion from 'char' to 'const char*'
noteuv2:74: error: initializing argument 1 of 'int strcmp(const char*, const char*)'

Try this, instead:

        if(strcmp(&responseBuffer[len-5], "ready") == 0)
        {