Is Serial1.available() useful for slow responding devices?

If data is sent to a serial device via Serial1.write(), then the next line of Arduino code is Serial1.available(), and no bytes are available, but there should be, but arent because the serial1 device appears to be slow, then what? Or instead, should I use Serial1.readBytes() orSerial1.readBytesUntil() after setting Serial1.setTimeout()? And just forget using Serial1.available()?

What is the actual concern ?

Serial.available() returns the bytes available in the 64 character buffer.

When the expected number of characters is reported, read that number out of the buffer.


You could check for a termination character with Serial.peek().

Using .write() has no effect on .available(), as your first sentence seems to suggest.

Are you expecting the device to echo back characters it receives?

I would suggest to study Serial Input Basics to get a better grasp on the serial port

This is a great example for writing non-blocking code.

Your code probably has other things to do than wait for something that may never happen…

Your code should continue twiddling its toes, and regularly check for Serial.available().

When something arrives, it’s up to up you to stuff the newly arrived characters into a buffer, test for some specific match, or just keep on twiddling.

Your LEDs can keep blinking, or stepper keep on stepping until YOUR requirements are met.

Here's a revision of the original post. --> It is possible that the serial1 device might not send out a timely response as would be liked, so serial1.available() would report no bytes received. But some millisecs later, serial1 likely gets around to producing a response. So, should I loop serial1.available() to catch a potentially slow response, or go to the other (time out) functions that I mentioned in the original post? Which approach is preferred? Or does it make any difference? Im thinking putting Serial1.available() in a never-ending loop until there is a response may not be a good idea... Maybe looping a finite number of times?

Implement a state machine. In the first state you send data, in the second state you check for the response.

@walshrd, your topic has been moved to a more suitable location.

What? A state machine? Ok. That was a helpful answer. I'll see if I can find a state machine in Idaho or Utah.

Shouldn't be too difficult :grinning_face_with_smiling_eyes:

Else Google can help you.

You didnt understand the post.

Well Jackson, I have studied Serial basics and my question is not answered there. If it is, quote it for me, since you have spent no time in being helpful.

This should give you the idea.

Place below near the top of your code

// enum with states for communication
enum COMMSTATE
{
  SENDCMD,  // send the command
  RCVREPLY, // wait for complete reply
  PROCESS,  // process reply
  COMPLETE, // done
};

Next loop() can be something like below. I've added a button that, when pressed, starts the process of sending, receiving and processing. It's only for demo to give the idea and will not compile. You can replace ISPRESSED by either LOW or HIGH depending on the wiring of the button.

void loop()
{
  // remember what we're doing regarding serial comms
  static COMMSTATE commState = COMPLETE;

  byte btnState = digitalRead(somePin);

  // state machine
  switch (commState)
  {
    case SENDCMD:
      // send the command
      ...
      // change state
      commState = RCVREPLY;
      break;
    case RCVREPLY:
      // receive data
      receiveWithEndmarker();
      // if all data received
      if (newData == true)
      {
        // change state
        commState = PROCESS;
      }
      break;
    case PROCESS:
      // process the received data
      ...
      // indicate that it's completed
      commState = COMPLETE;
      break;
    case COMPLETE:
      // wait for button to be pressed
      if (btnState == ISPRESSED)
      {
        commState = SENDCMD;
      }
      break;
  }
}

The variable newData comes from Robin's Serial Input Basics; receiveWithEndmarker() needs to be adjusted to your needs.

I’ll go be helpful elsewhere. Good luck

I’m so happy about the possibility now to ignore members. You’ll be my first !

1 Like

I will try to give you a different perspective on what I think you are asking, in addition to the excellent answers you have already had.

You seem to think serial1 is in some way especially slow, it's as slow (or as fast if you prefer) as any other serial port. How fast depends on what baud rate you set. However, terms like 'fast' and 'slow' are subjective and a bit meaningless. A serial port set at 9600 baud can handle approximately 1000 characters per second, which is extremely fast compared to even the fastest that anyone can type. From the processor point of view the processor can read a newly arrived character in the serial input buffer, then make itself a cup of tea, relax for a bit with its favourite novel and after reading a chapter or 2 go back and inspect the input buffer to see if there's anything new to read. Most of the time there won't be.

That's the background, now to your question, or at least what I think you are asking. You send something out of the serial port to some external device, then wait for that device to send something back, I believe that's the scenario you are describing. Just sending a single byte takes an age in terms of processor speed. Once sent the other device has to do its thing and respond. Even if it responds pretty much immediately there is still the slowness of the serial port to deal with before its response arrives, and all that assumes 1 byte. If there are multiple bytes it takes even longer. You also have to consider that the other device might never respond, you can't just sit doing nothing waiting for a byte that might never arrive.

The solution is, as noted, a state machine. Look on this site for the tutorial doing several things at once (I am typing on my phone, looking for and posting links is a pain otherwise I'd post a link for you). Also look for blink without delay. There are other tutorials and topics that cover this subject and all the code in any of my tutorials uses state machines. This is one of the most important concepts you can learn because once you understand it you can write fast, responsive multitasking code.

Thank you for this. It is helpful and appreciated. The serial device I am talking to is ancient and its firmware doesnt seem to rank serial response as a high priority as the device does lots of other priority operations on a high-traffic RS485 bus before it seems to have any interest in queries from the RS232 com port. It's not a general problem with any serial1 device, it's specific to this device only.

Ignored.

jremington: With an arrogance like yours, and your inability to understand a simple question re Serial1.available(), why not just ignore the question to begin with? Im not an expert, that's why I turned to the forum. Sorry you didnt help.

I think the issue you’re missing here, is the Arduino could handle twenty of your devices concurrently using the right code.

A state machine model has been suggested and demonstrated, but you seem intent to hold on to an awkward ‘sequential’ method of operation.

If it’s so important the processor doesn’t do anything else until the reply is received, perhaps delay() will stop things as long as needed.

Thanx for your input lastchancename. I am aware that the Arduino will handle inputs quite well. But as Ive said,
my "problem" occurs when my RS232 (ancient) device can be slow to respond back to my Arduino. The Arduino code
would not be awkward as it could be (1) a simple finite loop that calls Serial1.available() n number of times with delay()
or (2) uses Serial1.readBytes and waits until the device sends something or times out (by setting Serial1.setTimeout()).
If you had this problem with this unpredictable, often slow device, would you loop Serial1.available() with a small delay()
or use Serial1.readBytes? That's all Ive wanted to know. This will be very simple, straight-forward code that I can write.
Im looking for advice concerning these 2 options.