04 Jun 2021 - tsp
Last update 04 Jun 2021
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 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:
xorbased checksum (a packet is valid if all bytes exclusively or’ed together are
0x00- this checksum can be calculated by leaving out the checksum field and
xorall bytes together).
Since I’m sometimes using
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: