TT Lab
Get started
Learn Learning paths Courses

The Sensor Is Fine. The Board Cannot Understand It

The Characters Arrive, but I Cannot Read Them

Continue in TT Lab

In one line

UART has no clock line. So both sides must trust the same bit time, and when that trust is broken, the frame falls apart from the back.

Why this was needed

A sensor sends one line of measurements every 3 seconds. Unreadable characters are printed on the terminal, yet the length is right and the line breaks arrive on time. It is the same if you change the sensor and the same if you change the cable. A pattern like this is almost always a problem of speed. If the wiring were broken, nothing would arrive, and with noise it would be garbled only occasionally, not garbled the same way at the same place every time.

The reason UART is vulnerable to this kind of fault is that it is designed that way. With only one wire, there is no way to tell "now is the bit boundary". The sending side lays out bits with its own clock, and the receiving side cuts them with its own clock. There is no guarantee anywhere that the two clocks are the same. All there is is one chance per frame to align the position, the start bit.

How it works

When idle, the line is high. When there is something to send, it pulls the line low for one bit time, and this is the start bit. The receiving side aligns its clock by looking at this falling edge. Then the data bits come starting from the low-order bit, a parity bit is added depending on the setting, and it ends with a stop bit that is high for at least one bit. The setting called 8N1 means 8 data bits, no parity, and 1 stop bit.

What the receiving side does is simple. It reads the point (k + 0.5) bit times away from the start edge as bit k. The reason for choosing the middle of the bit cell is that it is farthest from the edges.

      시작    d0    d1    d2    d3    d4    d5    d6    d7   정지
   ────┐     ┌─────┐           ┌─────────────────┐     ┌────────
       └─────┘     └───────────┘                 └─────┘
        ^     ^     ^     ^     ^     ^     ^     ^     ^     ^
        표본은 언제나 칸의 한가운데

This structure sets the error budget. In 8N1, the last position read is the stop bit, which is 9.5 bit times from the start edge. To not leave its cell there, the accumulated error must stay within 0.5 bit, so the difference the two clocks allow is 0.5 ÷ 9.5, about 5.3 %. This number is not copied from a specification; it comes straight from the frame structure. So the misalignment shows up not at the front of the frame but from the back. The front bits still have margin left.

The most common path by which this error arises in embedded systems is not noise but the divisor. If the firmware set the divisor assuming 12 MHz, and the crystal oscillator on the board is 11.0592 MHz, the baud rate that comes out with the same divisor is 9600 × 11.0592 ÷ 12 = 8847.36 Bd. That is over 8 %, so it leaves the budget above. This course's capture file is exactly that situation, and in the waveform it appears as the bit boundaries drifting steadily within a frame.

Two safeguards appear here. A framing error means the stop bit position was read low. When the speed is off, the last position goes wrong first, so it is caught well. Parity is a method of keeping the number of 1s odd or even, so it is caught only when an odd number of bits are flipped. If an even number are flipped, it passes as is. The sigrok UART decoder documentation also treats these two separately as parity error and frame error (documentation).

The fix is surprisingly easy. The answer is inside the capture file. If frames were sent back to back without a break, all the edges lie on the same bit grid, so between any two edges is an integer number of bit times. Take a coarse value from the shortest interval, and as you lengthen the baseline, re-round that integer, and the precision goes up. You must not do it in one step with the whole length — the moment the coarse value's error times the number of bits exceeds 0.5 bit, the rounding picks a wrong integer.

What it looks like in the field

When you get a report that "characters are garbled", first ask. Is the same place garbled every time, or is it random? If the same place, it is speed, and if random, it is an electrical problem. And check whether the framing error counter goes up. If it goes up, it is timing, and if it does not go up but the values are strange, it is the worse case — undetected corruption.

You often see design documents that turn parity on and say "now it's safe". In this course's 8E1 capture, 10 of the 11 frames were wrong, yet parity and framing caught only 8. Three passed with wrong values without any indication. Parity is a signal that "there is a problem", not a guarantee that "there is no problem".

What you will do in the next lab

You get three capture files. One is normal and two have a misaligned clock. You write the threshold function and the frame decoder yourself, thin out the samples to find the point where reading collapses, and re-measure the real bit time from the misaligned capture to revive the readable sentence. Finally you count in numbers what parity caught and what it missed.