Serial.read() best practice?

After some forum searching and resource dredging, I’d like to see what the community consensus is regarding best practice when implementing a serial reader? (specifically Serial1). UART polling seems crude, as does potential timer callback polling methodology.

Am I missing something?
What do the Particel guru’s recommend?

Thanks in advance for weighing in.

Not sure whether you already gathered, but the actual HW communication is interrupt driven and only feeds the received data into the RX buffer while another interrupt driven task pushes the TX data in the respective buffer out over the lines.
So, armed with this knowledge you can choose the best practice for your use case - there is no general answer that’s best for all cases.

ty for your reply @ScruffR -

I can’t say that I gathered that, specifically… the .serialEvent() reference implies there’s an ISR that’s buffering incoming stream data:

"The serialEvent functions are called in between calls to the application loop()"

Is this what you are referring to?

Actually serialEvent() is a misleading name since it’s not event driven what-so-ever (and I had many discussions about this with Particle).
serialEvent() and its siblings is just another function that’s called in a while(1) inside the main() function of the system

like this

void main() {
  doSomePreps();
  setup();

  while(1) {
    loop();
    serialEvent();
    serialEvent1();
    serialEvent2();
    serialEvent3();
    doSomeCloudStuff();
  }
}

So no, I’m not refering to that.
But you can rely on the RX buffer to receive data (almost completely) independent of your code - as long you flush the buffer quicker than it’ll be filled with more than 63 bytes.

Depending on your baudrate and rate your sender is hammering your RX line you can calculate how much time you got to play with between your reads.

Hmm, I didn’t know that. That’s a bit disappointing. I might as well put the Serial handling code inside my loop function.

1 Like

Yup, it’s a bummer and even more the history of it.

Arduino intended to have this feature event driven - hence the name - but due to the limited power of the ATMEL chips used for the first Arduinos they degraded the function to what it is now (keeping the name tho’).
And now the sad part: Although now we’d have the power to pull this off correctly, we “need” to keep “compatibility” to a flawed design keeping a “lie” alive.

1 Like

I lazily put my GPS Serial port character parsing in there. Works great and forgot about it. But in the back of my mind I had thought someday I’d need to look into interrupt priorities and atomicity to see if the code I had in there might have intermittent issues. On the plus side, I won’t need to do that now.

1 Like

I understand the difference @ScruffR… without a receive ISR the best one can do in my mind is fire off an interval timer and pull data from the RX buffer.

I agree, it’s crude and poor practice…

That’ll definetly work, but might be overkill for most use cases IMO.

Even with 115200 baud and a continously talking transmitter you’ll have 5+ milliseconds before the RX buffer gets overwritten.
Often you don’t have that chatty sources or you got plenty redundancy in your data where a few dropped bytes don’t matter.
And in many cases 5ms is a lifetime to get back to flushing out the received data.

So as said, the task dictates the means.

The downside to polling for available char’s in one’s loop are blocking operations, hence my notion for ensuring one can service the receive buffer when needed. Is there a compendium of blocking operations?