Using my own program on the PC side, I am polling data from a device in half-duplex way (like in old walkie-talkie style) through a USB port.

This is serial communication (Baud rate is 9600 bits/s, 8 data bits, 1 stop bit, no parity). So one can't simultaneously send and receive messages. The PC side is master, the device side is slave. When the device (using an embedded system) receives a certain byte array, it processes it in a few ms of time and then sends back a byte array in response to the PC (my program then processes it).

The manufacturer told me to add a delay between sending and receiving such telegrams. And the protocol is fixed at 9600 baud rate meaning that one byte takes around 1 ms to send or receive. So if I send 10 bytes as command and receive between 10 and 50 bytes I would need to introduce a minimum of 60 ms of delay. But to be on the safe side I want to use a 300 ms delay or even more.

My question is, how long can the received data wait at the received buffer? I mean, is there an upper limit for the delay time I can use in my case? And does that have something to do with timeout?

  • \$\begingroup\$ It sounds like you are wanting to add a delay that is proportional to the message length. I think what the manufacturer is suggesting is a fixed delay imposed by the slave before sending its reply to the master. \$\endgroup\$
    – Andy aka
    Commented Mar 24, 2021 at 9:36
  • \$\begingroup\$ He just means the min delay needed can be calculated by baudrate and total amount of data sent and received plus some ms processing time. But there will be some delay inside PC as well. What I was wondering if I add safety margin delay is it fine or not. I check even I need 50ms some cases I still get response when I use 1000ms delay. But wanted to be sure about the logic behind. Meaning that how long the received telegram can live in the received buffer. This is more about PC's serial COM inners rather than MCU's. \$\endgroup\$
    – user1245
    Commented Mar 24, 2021 at 9:41
  • \$\begingroup\$ Depending on USB UART chipset and settings, it could really be anything. Even the transmit delay, not just the receive delay. Perhaps the approach of sending command, waiting with a delay, and then expecting to have received all response bytes is not right. Is there an established protocol being used, so you can e.g. expect a response to a certain command being always the same length etc? Which device it is? Link to protocol manual please? \$\endgroup\$
    – Justme
    Commented Mar 24, 2021 at 10:19
  • \$\begingroup\$ Yes I can predict the number of bytes received so it is in protocol. So I send the command bytes and after some time passes the input buffer should be ready. I count the number of bytes at the port but after a delay before reading it to form an array in my program. So I introduce large enough delay. The polling stucks if I dont do that. One thing I dint try to monitor number of received bytes and then read the buffer instead of delay. \$\endgroup\$
    – user1245
    Commented Mar 24, 2021 at 10:38
  • 1
    \$\begingroup\$ Usually there isn't any maximum delay. \$\endgroup\$ Commented Mar 24, 2021 at 12:46

4 Answers 4


This is serial communication. So one can't simultaneously send and receive messages.

Now, this is absolute nonsense. Even if you have half-duplex communication, you can still send and receive simultaneously. You simply will be reading back whatever you are sending.

You did not answer my question about actual wiring, but since you've mentioned USB and did not mention any special hardware (like resistors or diodes) I am assuming you are using one of the ubiquitous Serial-to-USB dongles in full duplex wiring (Rx, Tx and GND). This means you can read and write simultaneously, and will not be even reading your own transmissions, unless the device echoes them.

The challenge-response protocols between device and PC are dime a dozen, for example this is how most of the BMS boards work. But this has nothing to do with actual half-duplex communication, even on microcontroller level. On PC, where the buffers and hardware protocols are managed for you by the OS it is even less relevant.

All you have to do is set up continuous reading (polling) and processing of the incoming packets, then send the request from time to time. No delays whatsoever.

If your device's protocol has specific packet header, EOF or embedded length, then you don't need anything else but the correct parsing code. If there is nothing like that (which is rare in serial communication) then you need to use some kind of timekeeping in the receiving code.

Something like "If more than xxx ms passed since I received last byte I can assume there will be no more coming and I can process whatever I've read so far. Then I can send another request".

And "If more then yyy ms passed since I've sent the request and I did not receive even one byte in response then there must be something wrong with the device". At which point you can attempt to send another request, or do whatever you want to do.

You can process responses as the data is coming or you can accumulate it until entire packet received. If the protocol has some kind of validation (e.g. checksum) or variable length is is almost always better to wait, because parsing code will most likely depend on it.

It is as simple as that. I don't understand why you and others keep discussing the timing and delays. When you code for PC, there is already so much latency introduced by the hardware and system stack that timing is usually irrelevant. The PC approach to communication is "let's transmit as fast as possible on the hardware level, and then put huge buffers between that and sloppy software so it can process data whenever I (OS) let it do some work". This is completely different from MCU world where just-in-time processing is usually required.


If I were you I would try it out. It looks to me like a case where it is hard to determine afront what will actually happen. Let it run and try different delays for testing.

I think the hardware wouldn't discard the buffer that fast. What software are you using and what hardware/software is your slave would help a lot answering more precise I'd say. :-)

In a SPI-Interface it can f.e. happen that if you do not pull up csn after sending your data, the buffer will not be emptied at all (until you shut down the device since the memory is volatile). I'd assume a similiar behaviour for UART.

  • \$\begingroup\$ So it can stay there hours infinite therotically? At master side I use C# .Net WriteAsync and then Task.Delay(100) and the ReadAsync. Slave is ARM based embedded system device a black box for me, I cannnot update it. Do you know what is meant by timeout of the port in this context? \$\endgroup\$
    – user1245
    Commented Mar 24, 2021 at 9:34

It really depends on how your USB to serial bridge works. A USB peripheral can be polled at maximum each millisecond, with 8ms and 32ms popular service times. For this reason every USB-serial bridge has an internal buffer to match the communication port with the USB transfer.

As an example the FTDI FT232R (a quite popular part) has 128 bytes in one direction and 256 bytes in the other. For optimizing the transfer usually it waits a bit before signalling received data: in this way it can send more bytes in an USB transfer and this is efficient.

This also mean that you actually get the bytes a bit later in respect to when they actually arrived: some millisecond to about 10ms is typical. There are also configuration options for the chip (using its special software) to tune the USB transfer interval or how much to wait before sending or receiving the data; it's actually quite complex and depend on your chip.

In short: usually you can't control serial transmission timing at the millisecond level. It's a serious issues for some protocols like MODBUS which relies on intrabyte timing for packet framing. As for your 300ms wait you could assume that about 10ms after your write request your data should at least have started transmitting (if you have some control on your USB bridge, like a flush command, even better). So just do a sleep after writing and let the OS do the rest.

In fact, unless you are using an RTOS your 300ms sleep would be probably a bit longer

  • \$\begingroup\$ The thing is for 10byte transmit and 10byte receive at 9600 it takes minimum 20ms and lets say processing time is 5ms and now you mention a delay due to bridge and lets say that is 20ms worst case. That makes 50ms more or less. So is there anything wrong to use 300ms or 500ms instead to be safe here? Because I want to be sure about these if other computer uses this with another USB bridge. It is okay for me to put a delay up to even 1000ms. But cannot estimate any maximum delay(sleep or wait) for the delay between sending and receiving. \$\endgroup\$
    – user1245
    Commented Mar 24, 2021 at 13:11

how long the received data can wait at the received buffer.


is there an upper limit for the delay time I can use in my case?


The manufacturer told me to add delay between sending and receiving such telegrams ...

Beware of what other say (me included): they may be wrong.

To do the best, you should know how things go, implement minimum delays and try instead reasonable waiting times.

Typical case: the device understands a command only when all the bytes are arrived. After a certain time (about 10 ms, but there is a command that takes 10 seconds) the device replies. The reply comes in a burst but, as before, characters are spaced by about 1 ms (@9600 baud).

First, you know that until your command has shifted out, the device will not reply. You can use a delay or, more simply, you can add this time to the total time you will wait later.

Second, may be you know that, for some command, some more time will be needed. When you send that command, you can wait more time because you already know. Or you can add that time to the total waiting time.

Here is approach 1:

  1. send command
  2. wait() (sleep?) 5 + 1 ms for every byte sent
  3. if the command sent needs 10 seconds more, wait() 10 s
  4. Call readslave(0)

Approach 2 is:

  1. Send command and set mstowait = num_of_char_sent
  2. command needs 10 s more? mstowait += 10000
  3. Call readslave(mstowait)

Here, the readslave() function is a function that waits up to mstowait milliseconds for the first char, then the timeout is reduced to something reasonable, for example 5 ms (or 10) for every subsequent byte. This routine reads all the data it can, not just a fixed number. This prevents master and slave go out of sync. Another good thing to do is to call readslave(5) before sending a command and waiting a reply. This also help to keep master and slave in sync.

The proposed algorithm has these advantages:

  1. Low minimum waiting time
  2. ...but in some way flexible
  3. Depending on the cases (big latency), one can send a command, go to do something else and, when the receiving routine ends, go to see the reply.

A few things has to be always accounted for:

  1. Transmit (and receive) error happens. They happen. If the dialog can be checked for validity, it is better. A character can be literally "invented" by something else, for example a noisy spike. Noise can (rarely) cancel an incoming character.

1b. If the device checks incoming commands for validity, and it finds a non valid command, what it does? Does it send back an error? Or it stays quiet? What happens if NO device is connected? Does the PC keep to transmit commands, wait a reply, then repeat over and over?

  1. Serial communication is asynchronous by definition, but even more on a PC (multitasking) and even more with USB dongles. Don't assume that you send 5 bytes and 6 ms later they have been transmitted. If there is a library function that says how many characters are left to transmit, you can be sure. Otherwise you must account for a reasonable margin, dependsing on the PC and USB dongle.

  2. Half-duplex communication are simple to manage, but master and slave can go out of sync. If the reply of a command has a known length, it is good to check the correct length of the reply, but all the received characters has to be read, otherwise they will go in the next command-reply.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.