Mini note on robust serial communication with microcontrollers

04 Jun 2021 - tsp
Last update 04 Jun 2021
Reading time 3 mins

Everyone who has built custom electronics - be it for home automation, in the lab or for other purposes - knows this problem. You have a rather convenient serial interface that is easily accessible - just set the Baud rate, start and stop bits as well as parity bit configuration and you’re good to go - most of the time with hardware support. You can use USARTs for different communication protocols like RS232, similar TTL and CMOS level interfaces, RS485, etc. Usually it works great - until some noise brings your devices out of sync. This usually happens for sure after some time of operation even on small scale systems but is happening more often in noisy and large scale environments. So the question arrises - how to handle that problem?

Well basically when using the UART it’s pretty simple. Since the UART does not transmit any clock signal one can at least be sure that it will finish to receive a full word of data - it will just contain garbage. So to bring the clocks back into sync is rather simple by just introducing some delay and then starting over with the next start bit. Getting into sync with the higher level logic is somewhat more problematic since one has to detect the invalid reception of additional bytes which might be a problem when using TLV encoded packets as well as determining the point in the data stream that the next message starts.


The simple solution - using packets

The simplest solution for the problem lies in the usage of packets. Each packet should include a start of packet marker. If you do have a byte sequence that will never occure anywhere else in your data packet you could easily use this packet. If not you can use it in conjunction with a checksum.

The idea is rather simple:

Ensuring the next packet will be most likely received

Since I’m sometimes using ESP8266 and ESP32 USARTs where microcontrollers are transmitting some ROM bootloader information during boot or are working in noisy environments and want to ensure the next packet is most likely received one can add another procedure: Simply clobbering the line with some data bytes that are not containing a start of packet marker. This finished previous packets for sure - hopefully with an invalid checksum. One just has to transmit at least as many bytes as maximum packet size minus one. The next start of packet will then be received correctly.

To ensure packets are received one should really transmit an acknowledge after every data packet. In case the acknowledge is not received during a timeout the jabber procedure described above should be used and then the packet should be sent another time after a short timeout that allows the USARTs to finish the current word reception timeslice for sure.

This article is tagged:

Data protection policy

Dipl.-Ing. Thomas Spielauer, Wien (

This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support