[SOLVED]arduino-esp8266 read serial data

Sometimes Im not getting all the chars that esp is sending but its very hard to detect most of the time this function is working as it should. Are there any mistakes that Im missing or any suggestions how to improve?
Thanks.

void listener(char a[]) {

  char serial_stream = 0;
  unsigned int  i = 0;
  unsigned long _time = 0;
  const unsigned int max_time = 10000;
  const byte delay_time = 1;
  bool flag=false;

  _time = millis();

  while ((millis() - _time) <= max_time) {

    if (mySerial.available() > 1) break;

  }

  while ((mySerial.available() > 0) && (serial_stream = mySerial.read()) != '\n') {

        if (serial_stream >= 32 && serial_stream <= 127) {
        flag=true;
        a[i] = serial_stream;
      if (a[i] == '>') {
        while (mySerial.available() > 0) mySerial.read();
        break;
      }
      _time = millis();
      while ((millis() - _time) < delay_time);
      Serial.write(a[i]);//write to serial window
      i++;
    }
  }

   if (flag) a[i + 1] = '\0';

  return;

}

don't post snippets...

what is mySerial and how is this configured? (if it a SoftwareSerial port at 115200 bauds, you should not expect fantastic results)

You realize you wait to have 2 chars to exit the initial wait loop?if (mySerial.available() > 1) break;

when you do this

  while ((mySerial.available() > 0) && (serial_stream = mySerial.read()) != '\n') {
..
  }

you read super fast and possibly empty the buffer, maybe without having read all the input that's still coming in, then mySerial.available() with return 0 and you'll exit without having read all the input.

I would recommend your read Serial Input Basics to see how to deal with Serial correctly.

Softserial at 9600.
I put 1ms delay between reading chars (const byte delay_time in while ).
I have read serial imput basics by Robin2 but still cant see how to inplement that in my case.

Sometimes I`m not getting all the chars that esp is sending

How do you KNOW that?

but its very hard to detect

If the sender was REQUIRED to send an end-of-data marker, then it would be SIMPLE to detect that you got that marker.

serial_stream = mySerial.read()

I'm sorry, but serial_stream is a stupid name for a char variable.

      if (a[i] == '>') {
        while (mySerial.available() > 0) mySerial.read();
        break;
      }

You apparently ARE sending an end of packet marker. When it is found, throwing away all unread data that followed it is hardly the mark of the sharpest crayon in the box.

surepic:
I put 1ms delay between reading chars (const byte delay_time in while ).

at 9600 bauds, a 1ms delay means roughly less than 1 extra character can arrive into your buffer. so you are likely to starve. --> don't try to second guess asynchronous communication by adding synchronous wait times, it's a recipe for failure...

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R

Ok. Jml pointed right to my first while loop no sense to wait for 2 chars anyway it will exit after timeout but will change to 1 char.

So esp in at command mode is sending stringns terminated by new line char. But when in transmission mode (‘>’) there is no terminating char. I checked with docklight its sending just >. So im catching that char and breaking the loop as you see to deal with that case.

@PaulS
I was supprised you didnt noticed char array named “a” :slight_smile:
How i know that sometimes im missing chars because im echoing all data back that im sending.
After > there is no data to come thats the reason to break the loop.

I read that st 9600bps gap between data is 1.04ms thats why i put 1ms delay knowing thats not the way i would like to solve that problem.

Robin2 i’ve read your article many times and most part of this function is from uour tutorial but cant go any further.

After > there is no data to come thats the reason to break the loop.

If there is no data, then why do you read and discard data?

I was supprised you didnt noticed char array named "a" :slight_smile:

I did. I don't understand this statement, though.

How i know that sometimes im missing chars because im echoing all data back that im sending.

Look at your code, and where you actually print what you receive, and see if YOU believe that statement. I certainly do not.

Putting EVERY { on a line BY ITSELF and putting EVERY } on a line BY ITSELF and using Tools + Auto Format would make your code MUCH easier to read.

thats why i put 1ms delay knowing thats not the way i would like to solve that problem

If you knew that it was wrong, why did you do it anyway? You want NO delays. You want to read data as fast as possible, so you don't miss anything.

You need to post ALL of your code. This is not snippets-r-us.

@PaulS
About data after > i realized while i was replying to your previous question. You are right no need to check for anything after >.

Serial.write is right after filtering unnecessary chars to understand what string will be formed at the end. Now you will ask “what unnecessary chars?” Chars that are being sent from esp right after restart and are readable only at baud rate 74880. Thats the reason for filtering in if.

Whole code was autoformated with ctrl+t before posting. I edited 2 lines of the code in topic couple times that may cause it look unformatted. And I apologize for that.

Why i put 1ms deay knowing beforehand thats not right way because as follows from reply#6 i couldnt think of better solution. And from all solutions that came to my mind i picked the best one.

Couldnt find any restriction in forum about posting functions,statements or sketch.

Currently i am having issue only within this function other functions are functioning properly.

Using delay() will not help you out. As Paul explained you need to build code that checks if something is available to read, is so read it, if not go do something else.

You need to have a state machine. First state is “waiting for start sequence”, then once you have received that, the second state is “acquiring message” until you receive the end sequence where you go to a “message received” state which should trigger analysis of your message, and once handled you. Go back to your “waiting for start sequence” state.

surepic:
Robin2 i’ve read your article many times and most part of this function is from uour tutorial but cant go any further.

I don't see any calls to one of my functions in your code. Perhaps you need to post the latest version of your complete program.

Quote from Reply #9

you need to build code that checks if something is available to read, is so read it, if not go do something else.

That is what my code does.

...R

Robin2:
Quote from Reply #9That is what my code does.

exactly ! hence my recommending your tutorial back in post #1

J-M-L:
exactly ! hence my recommending your tutorial back in post #1

There is an old saying "you can take a horse to water but you can't make him drink" :slight_smile:

...R

in french it's with a donkey ("on ne saurait faire boire un âne qui n'a pas soif")
:slight_smile: :slight_smile:

J-M-L:
in french it's with a donkey ("on ne saurait faire boire un âne qui n'a pas soif")
:slight_smile: :slight_smile:

Yes indeed. Having a "soif" is a very important part of learning.

...R

Robin2:
Yes indeed. Having a "soif" is a very important part of learning.

...R

I'm completely lost here. I got google.translate to translate the phrase:

you can not drink a donkey that is not thirsty

A thirst for learning I'd agree with. A thirsty for learning? I don't know. I'm still learning.

But, I suspect that google failed miserably.

PaulS:
A thirsty for learning?

Pedant :slight_smile:

...R

void listener(char a[], unsigned int timeout){
  
  char serial_stream = 0; 
  unsigned int  i = 0; 
  unsigned long _time = 0;
  bool flag = false;
_time=millis();

do{
if (myserial.available()) {
   serial_stream=mySerial.read();
    if (serial_stream >= 32 && serial_stream <= 127) {
      flag=true;
      a[i] = serial_stream;
      if (a[i] == '>') {
        Serial.write(a[i]);
        a[i+1]=‘\0’; //need to make it string
        return;
      }
      Serial.write(a[i]);
      i++;
    }
  }
}while((serial_stream!=‘/n’) && (millis()-_time)<timeout);

  if (flag) a[i + 1] = '\0';

  return;
}
[code]

What is the purpose of Reply #17 ?

...R

PaulS:
google.translate to translate the phrase:

you can not drink a donkey that is not thirsty

But, I suspect that google failed miserably.

definitely that!

it translates as "you cannot force a donkey that is not thirsty to drink"

it's also true that it's pretty hard to drink a donkey, wether the donkey is thirsty or not :slight_smile: