esp8266 output not added to String

Hi,

Hardware: an esp8266 12S that is attached to an Arduino Uno, (actually an Elecrow espduino). Software Arduino IDE 1.8.10 on a Linux box.

I am trying to read data adding them to a string. Funny thing is that the esp8266 keeps emitting characters, but that after a few dozen or so characters they are not added to the string any more.

If the function below is called with e.g. debug=3, I see characters coming in as expected, but the string response stops growing after 40 bytes.

This behaviour is erratic in that in some sketches the function works fine, but in other sketches not. I tried all kinds of delays, both as 'delay(xxx)' and as a parameter to te function, but no luck.

It does not seem to be memory related. The output from the compiler says: Sketch uses 17110 bytes (53%) of program storage space. Maximum is 32256 bytes.
Global variables use 1348 bytes (65%) of dynamic memory, leaving 700 bytes for local variables. Maximum is 2048 bytes.

I really am beating my head to the wall now.


String sendData(String command, long timeout, int debug)
{
// debug=0 : geen output
// debug=1 : alleen commando
// debug=2 : commando en output

long int timein = millis();
String response;
char ch;
int t=0,x;

if (debug>0) {Serial.print("command ");Serial.println(command);}

esp8266.println(command); // send the command to the esp8266
response = "";

while( (timein+timeout) > millis())
{
while(esp8266.available())
{
// The esp has data so display its output to the serial window

ch = esp8266.read(); // read the next character.
Serial.print(ch);
t++;

if (int(ch)>31) response.concat(ch);else response.concat(" ");

if (debug==3)
{
Serial.print(" ");
Serial.print(t); Serial.print(" - ");
Serial.print(int(ch));Serial.print(" ");Serial.print(response.length());
Serial.print(" ");Serial.println(response);
}
}
}

if (debug>1)
{
Serial.print("response: ");Serial.println(response);
Serial.print("bytes read: ");Serial.println(t);
}

return response;
}

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with ‘\0’ (NULL).

(Note that an ESP8266 has very much more SRAM than an Uno or Mega)

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

…R

Dear Robin, thank for your reply.

Originally this project was written on a WEMOS D1R2, which has enough memory and a much more friendly set of libraries for wifi. But it incorporated a fingerprint scanner and for some reason it started malfunctioning on the WEMOS. Also, I needed more pins.

Best thing would have been a LOLIN32, because then I'd have lots of pins and OTA updating, but the fingerprint library did not work at all on the esp32.

Anyway, following your suggestion and collecting the output from esp8266.read into a zero-terminated array of char, made no difference at all. The characters kept coming in but were not added to the array in exactly the same way. The array just stopped growing after a few dozen chars in exactly the same places as with the String.concat.

I will now attentively read your link on serial input. Hopefully there is something there that I did not yet try.

Dear Robin,
I have studied your examples, but there is a problem with them. As far as I understand they depend om single byte markers in the incoming data, such as ‘<’ and ‘>’ and the problem that you address is the fact that the normal serial functions are blocking.

However, if you are communicating with an esp8266 that in its turn reads a website such markers are very diverse. If you send AT codes they return strings like “OK” and when you try to attach to a webpage, you have to read the header of that page and then the page itself and extract the exact data that you want.

I tried to fit in your examples into a new sendData function, but to no avail.

What I (and many others, if I read all those forums correctly) is a fireproof ‘sendData’ function as in my first post, that sends AT sequences to the esp8266 and collects the output in a String or an array of char, without crashing halfway the process.

Paai

paai:
However, if you are communicating with an esp8266 that in its turn reads a website such markers are very diverse.

Are you sure there is not a simple linefeed character or carriage-return and linefeed to mark the end of the messages - if so my second example should be sufficient.

Another more complex solution is to monitor the time interval between successive characters and treat a longer gap as the end of a message.

...R