Reading +IPD response from serial.read() using Arduino UNO and ESP8266

I have a python server running on my PC and I am using an Arduino Uno (wifi enabled by a ESP8266 chip) as the client.
I can make the the server and client communicate using AT commands as shown below:

  SoftwareSerial esp (8,9);

       void setup()
       {
       esp.begin(9600);
       esp.println("AT+CWMODE=3");
       delay(100);
       esp.println("AT+CIPSTART=\"TCP\",\"192.168.8.100\",5555");
       delay(1000);
       esp.println("AT+CIPSEND=3");
       delay(100);
       esp.println("bbb");
       delay(100); }

The string "bbb" is recieved on the server and the server responds back, which is shown in the serial monitor as:

+IPD,19:the string is found

I want to read this response and use it back in the code for further conditional statements. But i am unable to do this. So far i have tried these methods.

1st method by using esp.readString() as shown below:

String buffer="";
    while (esp.available()>0) 
        buffer+= esp.readString();   
    Serial.print(i4);

2nd by using esp.read() as shown below:

String buffer="";
    char c;
    while (esp.available()>0) {
        c= esp.read();
        buffer+=c;}
    Serial.print(buffer);    // i have also tried using esp.write() directly for prinitng here intead of storing it in a buffer

These two methods returned with incomplete information in the response string buffer ie i only get:

    busy s...
    
    Recv 3 bytes
    
    SEND OK
    
    +IPD,19:the string

I can not get the entire response in the buffer as mentioned in the start. On the other hand if i execute the command AT+CWLAP and store its response in the buffer string, i get the entire thing. So i cant understand why is there a difference between the two.
Lastly i have also used esp.readBytes() as shown:

 char c[500];
    esp.readBytes(c,400);
    esp.write(c);

This code gives me the whole response sometimes but sometimes it just gives a long garbage value. But the times it does give me the complete +IPD response, it switches some of the alphabets ie the string is found becomes the strjng is gound
If anyone could help me out i'll be very thankful.

execute the command AT+CWLAP and store its response in the buffer string, i get the entire thing.

Can't you parse the part that you want from that? Please post an example of the received string.

So i cant understand why is there a difference between the two.

I am not sure which 2 you mean. Can you post the codes that you mean?

You should try not to use String (note bis S) objects. Their use can cause weird memory problems. Stick with null terminated character arrays or cstrings (strings [small s]).

Some good information on receiving and parsing serial data.

groundFungus:
I am not sure which 2 you mean. Can you post the codes that you mean?

I read that the Serial buffer can only hold 64 bytes at a time. So when i run this code:

   esp.println("AT+CWLAP");
   delay(1000);
   String str="";
  while (esp.available()>0) {
    i3+= esp.readString();
    }
 Serial.print(str);

I get the following output:

AT+CWLAP
+CWLAP:(4,"MBB_ZONG_25C7",-79,"78:52:62:29:25:c7",1,43)
+CWLAP:(3,"ZONG-MBB-E8372-470D",-46,"bc:75:74:a6:47:0d",7,50)
+CWLAP:(3,"rafaynet",-84,"b0:4e:26:07:28:78",2,36)
+CWLAP:(3,"citytt060",-60,"a4:2b:b0:a1:8a:ea",2,43)
+CWLAP:(3,"CharJi-8A3D",-82,"c0:5e:79:ff:8a:3d",6,147)
+CWLAP:(3,"PTCL-QADRI.",-93,"00:e0:92:00:01:40",8,25)
+CWLAP:(4,"Tenda_97B660",-70,"c8:3a:35:97:b6:60",8,46)

which is clearly greater than 64 bytes.
But when i connect to my server and send it a input string like this:

esp.println("AT+CIPSEND=3");
delay(100);
String i4="";   
 while (esp.available()>0) {
   i4+= esp.readString();       //this is done just to flush out the serial buffer so i can get the data i want
 }
esp.println("bbb");    // i need to store in a variable the response of the server the arduino receives when i give the server a stringlike this 
delay(100);
String i5="";
char c; 
while (esp.available()>0) {
   c= esp.read(); 
   i5+=c;
 }
Serial.print(i5);

I get the following result stored in i5 :

busy s...
Recv 3 bytes
SEND OK
+IPD,19:the string i

where as it should have been +IPD,19:the string is found

This is where i am stuck, i can not get this whole string into a variable to use in my code.

simsam:
I read that the Serial buffer can only hold 64 bytes at a time. So when i run this code:

If you use the examples in Serial Input Basics you can receive as many bytes as you wish - just change the value of the constant numChars

...R

Robin2:
If you use the examples in Serial Input Basics you can receive as many bytes as you wish - just change the value of the constant numChars

...R

I used the example 3 in this, i set the servers response as: "@the string is found!" and changed the startMarker = '@' and endMarker = '!' I changed the numchars to 100 as well
Still i got the same result.
+IPD,21:@the string

I have no idea why this is happening, i've been stuck on this for so many days now. please if youcould further help

You need to post the exact program that you used.

Also, it is easier to help if you respond within (say) 24 hrs while your problem is still in my mind.

...R

Look at my code in my post i have different problem but ipd thing solve by reading to char array until terminating ‘\n’ then process whatever you get and continue reading second line.

Robin2:
You need to post the exact program that you used.

Here is the code i used, i have add the code from your post in it as well:

#include <SoftwareSerial.h>

char a[100];
char cmd[100];
 
struct packet{
 char packet_type[15];
 char sensor_name[10];
 char payload[10];
 };

struct packet syn;

const byte numChars = 100;   
char receivedChars[numChars];
boolean newData = false;


SoftwareSerial esp (8,9);

void setup() {
  
 Serial.begin(9600);
 esp.begin(9600);
 
 
 esp.println("AT+CWJAP=\"SSID\",\"PASSWORD\"");   //i had used the actual ones here
 delay(5000);
 int i=0;
 char c[100];
 while (esp.available()>0) {
 c[i]= esp.read();
 Serial.write(c[i]);
 delay(10);
 i++;
 }
 
 esp.println("AT+CIPSTART=\"TCP\",\"192.168.8.100\",5555");
 delay(1000);
 i=0;
 c[100];
 while (esp.available()>0) {
 c[i]= esp.read();
 Serial.write(c[i]);
 delay(10);
 i++;
 }

 //Initiallizing the struct declared above
 strcpy(syn.packet_type,"syn");
 strcpy(syn.sensor_name,"temp");
 strcpy(syn.payload,"100.7");

 //Storing all the struct variables in one string to send it, i couldnt think of anyother way to do it for now
 strcpy(a,syn.packet_type);
 strcat(a,syn.sensor_name);
 strcat(a,syn.payload); 
 
 //len =sizeof(a);
 //Serial.print("len="+len);
 //strcpy(cmd,"AT+CIPSEND=");
 //strcat(cmd,len);

 esp.println("AT+CIPSEND=12");
 delay(2000);
 i=0;
 while (esp.available()>0) {
 c[i]= esp.read();
 Serial.write(c[i]);
 delay(10);
 i++;
 }

 esp.println(a);
 delay(1000);
 i=0;
 /*At this point after sending the string a to the server i get a response but the response gets terminated, i have written what happens in the question above  */
 recvWithStartEndMarkers();
 showNewData();
 /*while (esp.available()>0) {
 c[i]= esp.read();
 Serial.write(c[i]);
 delay(10);
 i++;
 }*/
}

 


void loop() {
//Here i am just sending arbritary data to the server for checking it
 esp.println("AT+CIPSEND=3");
 delay(1000);
 int i=0;
 char c[100];
 while (esp.available()>0) {
 c[i]= esp.read();
 Serial.write(c[i]);
 delay(10);
 i++;
 }
 esp.println("aab");
 delay(1000);
 
//again here i am supposed to get the serponce from the server but i recieve a truncated response after the +IPD from here

 i=0;
 while (esp.available()>0) {
 c[i]= esp.read();
 Serial.write(c[i]);
 delay(10);
 i++;
 }
 
 esp.println("AT+CIPSEND=3");
 delay(1000);
 i=0;
 while (esp.available()>0) {
 c[i]= esp.read();
 Serial.write(c[i]);
 delay(10);
 i++;
 }
 esp.println("bbb");
 delay(1000);
 i=0;
 //while (esp.available()>0) {
 //c[i]= esp.read();
 //Serial.write(c[i]);
 //delay(10);
 //i++;
 //}
 
  recvWithStartEndMarkers();
   showNewData();
}



void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '@';
    char endMarker = '!';
    char rc;
 
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

Robin2:
Also, it is easier to help if you respond within (say) 24 hrs while your problem is still in my mind.

...R

I am sorry about that as well i had internet issues that why, i will keep that in mind next time.
Thank you for helping me out

surepic:
Look at my code in my post i have different problem but ipd thing solve by reading to char array until terminating ‘\n’ then process whatever you get and continue reading second line.

Could you please give me a link of your post, i am new here so not quite familiar with how the website works, Thank you as well.

 delay(10);

Why? You can not hurry serial data along by stuffing your head in the sand.

c[100];

Well, that's interesting. Perhaps you should change that to

42;

That would be no less useless.

strcpy(a,syn.packet_type);
 strcat(a,syn.sensor_name);
 strcat(a,syn.payload);

So, a contains "syntemp100.7". How is the receiving end supposed to make sense of that?

//again here i am supposed to get the serponce from the server but i recieve a truncated response after the +IPD from here

You REALLY need to refactor your code. You have WAY too many places where you incorrectly read incoming serial data. You should have ONE function that reads incoming serial data. Call that ONE function as many times as you need to.

You REALLY need to properly indent your code. I'm tired of struggling to understand what your poorly laid out code is doing. And, with Tools + Auto Format so easy to use, there is no excuse for posting poorly indented code.

simsam:
Here is the code i used, i have add the code from your post in it as well:

I am confused.

I thought you are trying to read data from your ESP device and I presume that is what you are using SoftwareSerial for. However your code in recvWithStartEndMarkers() is reading from Serial. Shouldn't it be reading from esp?

If I have got things wrong please put me right.

...R

Robin2:
I am confused.

I thought you are trying to read data from your ESP device and I presume that is what you are using SoftwareSerial for. However your code in recvWithStartEndMarkers() is reading from Serial. Shouldn't it be reading from esp?

If I have got things wrong please put me right.

...R

Ohh i am so sorry about that i must have over looked that, i have corrected the code and changed it to esp.read(). I ran it again but still the same results.
Also the if statement in the showNewData() function is not executing. I wrote an else statement after that just to be sure and it was executed.

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    newData = false;
  }
  else
    Serial.print("not working ");
}

Also the if statement in the showNewData() function is not executing. I wrote an else statement after that just to be sure and it was executed.

The if statement IS executing. It is just not evaluating to true. Big difference.

Print each byte as it is received. Your idea of what the end of record marker should be, and the ESP's idea of what the end of record marker IS, might not be the same idea.

simsam:
i have corrected the code and changed it to esp.read(). I ran it again but still the same results.

You need to post the complete revised program in your next Reply.

You should not be reading data from esp anywhere except in recvWithStartEndMarkers()

...R

Robin2:
You need to post the complete revised program in your next Reply.

You should not be reading data from esp anywhere except in recvWithStartEndMarkers()

...R

Actually, recvWithStartEndMarkers() isn't the correct function to use. There is no specific start marker.

I will post the changed code in a little while.
Thankyou again for helping me with this issue

How are you dealing with response right after at+rst? There is a very long string comming from esp before ‘/n’ and before “ready”. I cant even copy that string to notepad its so long.

PaulS:
Actually, recvWithStartEndMarkers() isn't the correct function to use. There is no specific start marker.

Thanks. I'll watch out for that when the OP posts his latest code.

...R