Lesson 19 of 30 advanced 4 min read

Before this:Demodulation in code

Clock & symbol recovery

Key takeaways The transmitter sends symbols on a clock the receiver doesn’t share, so the receiver must recover the timing — figure out where each symbol begins and sample it at its centre. A timing error detector measures how early or late the current guess is, and a feedback loop nudges the sampling instant until it locks. A matched filter first sharpens each symbol. This is what turns a demodulated wave into clean bits.

The demodulator gives you a wiggling signal that steps between symbol levels — but when is each symbol? Without the transmitter’s clock, you have to find out. This lesson is that puzzle and its solution.

The problem: no shared clock

The transmitter emits, say, 4800 symbols a second on its own crystal. Your receiver samples on a different crystal, a little fast or slow, and started at an arbitrary moment. If you just read a symbol every so-many samples, you’ll gradually drift — and soon be sampling on the blurry transitions between symbols instead of their clean centres, where decisions go wrong.

sampling at centres = good on transitions = errors
Read a symbol at its centre (filled dots) and the level is clear; read it on a transition (open dots) and the decision is ambiguous. Clock recovery keeps you on the centres.

The solution: measure the error, correct it

Clock recovery is a feedback loop, much like the tuning loops elsewhere in DSP:

  1. Guess the symbol timing and sample there.
  2. A timing error detector looks at the samples around the guess and estimates whether you’re sampling early or late. (A classic one, the Gardner detector, uses the sample halfway between two symbols — it’s near zero only when timing is right.)
  3. A loop filter smooths that error estimate and nudges the sampling instant.
  4. Repeat every symbol. Once the error settles near zero, the loop has locked onto the transmitter’s rate and tracks its drift automatically.

Interpolation: sampling between samples

The correct symbol centre rarely lands exactly on one of your samples — it might be “37% of the way between sample 5 and sample 6.” So the loop uses an interpolator (a small filter) to compute the signal’s value at that fractional position. This is what lets timing recovery be smooth and precise rather than jumping a whole sample at a time.

The matched filter

Just before the decision, the signal usually passes through a matched filter shaped to the transmitted pulse. It maximizes the signal-to-noise ratio right at the symbol centres and suppresses smearing between neighbouring symbols (inter-symbol interference), so each symbol is as crisp as possible when sampled. GopherTrunk sizes this matched filter and the recovery loop from the channel rate set by the downconverter — which is why its decoder behaves the same regardless of the original capture rate. The RF path’s clock recovery lesson covers the same loop from the receiver’s view.

Quick check: why does a receiver need clock/symbol recovery?

Recap

  • The receiver has no shared clock, so it must recover symbol timing or drift off the centres.
  • A timing error detector measures early/late; a loop corrects until it locks and tracks drift.
  • An interpolator samples between samples for precise, fractional timing.
  • A matched filter sharpens each symbol first; GopherTrunk sizes it from the channel rate.

Next up: keeping the signal at a usable level as it fades — gain and AGC.

Frequently asked questions

Why does a receiver need clock recovery?

The transmitter sends symbols at a precise rate, but the receiver doesn’t share its clock and samples on its own slightly different clock. Without correction, the receiver would read symbols at the wrong instants and drift out of step. Clock recovery continuously estimates the correct sampling instant so the decoder reads each symbol at its centre.

What is a matched filter in this context?

A matched filter is shaped to match the transmitted pulse, and running the signal through it maximizes the signal-to-noise ratio at the symbol centres while suppressing inter-symbol interference. It’s applied just before symbol decisions so each symbol is as clean and distinct as possible when the decoder samples it.