Demo — DSSS Correlator#
The spread-spectrum playground shows what spreading does to the spectrum: the signal collapses into a spike while the jammer smears out into a low floor. This demo shows the arithmetic underneath that picture. Despreading is not a filter and not a subtraction — it is a correlation. The receiver multiplies the incoming stream by a code and adds up the product over one bit. Do that with the transmitter’s code, lined up with its chips, and the data bits reappear as correlation peaks. Do it with any other code, or at any other time, and nothing comes back.
The correlator#
Call \(r[t]\) the sampled stream at the antenna, \(c[\,\cdot\,]\) the \(N\) chips of the code the receiver is holding, and \(8\) the number of samples per chip. The receiver slides a one-bit window along the stream and correlates:
The \(1/8N\) normalises the sum, so a clean bit that is perfectly lined up reads exactly \(\pm 1\) — the transmitted bit itself. The codes are m-sequences: maximal-length shift-register sequences whose periodic autocorrelation is \(N\) at zero lag and \(-1\) at every other lag. That one property is the whole demo. Line the code up with itself and every chip product is \(+1\), so the \(N\) chips add coherently into one \(\pm 1\) decision. Slip the alignment by a chip and the products cancel down to the \(-1/N\) floor. Hand the receiver a different m-sequence and the products cancel the same way, at every lag. Three ways to read one stream, and only one of them recovers anything: right code and right time; wrong code; right code, wrong time.
One consequence is worth stating before you start, because it is the difference between a receiver and a random number generator. When the correlator is off the peak its dumps sit down on the \(\pm 1/N\) floor, and those tiny values still have a sign — in a clean channel, correlating with the wrong code lands every dump on exactly \(-b_k/N\), which is the data, inverted, at a thirty-first of its amplitude. Read the raw signs and you might conclude a wrong key merely flips the bits. It does not: a dump down at the \(1/N\) floor is not a decision, it is a sign on noise. A real receiver settles this with a lock detector — it only outputs bits once the correlation magnitude says it has actually found the peak. The demo does the same, counting a bit as recovered only when the dump is right-signed and at least a quarter of the clean peak. Below that the dump is drawn hollow grey and counts as no lock at all.
Interactive demo#
Walkthrough#
Read the three panels at the defaults — 31 chips per bit, J/S = +10 dB, the right code, no timing error. The top panel shows eight data bits and the chip stream that carries them: each bit is re-sent as 31 chips of the code, so the chips run 31 times faster than the data. The middle panel is what actually arrives — the tone jammer is several times taller than the \(\pm 1\) signal drawn faintly underneath it. The bottom panel is the correlator: a sharp \(\pm 1\) spike at every bit boundary, sitting on a floor of jammer residue, with a green dot where the receiver dumps and decides.
Raise J/S to about +15 dB and watch the signal vanish at the antenna. The jammer is now roughly eight times the amplitude of the chips, and the faint spread signal in the middle panel is lost inside it — yet the correlator peaks in the bottom panel are still standing and all eight bits still come back. Nothing filtered the jammer out; the correlation simply gathered 31 chips of signal coherently while the jammer, uncorrelated with the code, added up to very little. (Keep going and the link does eventually break — that is step 6.)
Switch to the wrong code. Same received stream, same receiver, one different key. The peaks disappear into the floor and the bit count drops to 0/8 — but look at how the dumps fail. In a quiet channel they go hollow grey: the correlator never found a peak, so there is nothing to decide. Turn the jammer back up and they go red instead: now the dumps are large enough to trip the lock threshold, but what they locked onto is jammer residue, so the signs are wrong. Either way the receiver has no data. This is the point of the code: with 31 chips the two keys differ enough that one is noise to the other. (At 7 chips per bit they are only seven chips long and cannot get far apart — the wrong-code trace stays noticeably livelier. Code isolation, like processing gain, is bought with length.)
Slide the timing error through one full chip. The peak is a triangle two chips wide at its base, so a small slip only shortens it: at a quarter chip the correlator still reads about \(0.75\) and the decisions hold. At one full chip the code no longer overlaps its own chips at all, the sampled value collapses onto the \(-1/N\) floor, and every dump goes hollow grey: no lock, 0/8, with the correct code in hand. One chip of slip is as total a loss as the wrong key. (Any non-zero timing error also pushes the eighth dump past the end of the record, so even a slip too small to break lock caps the count at 7/8; the tile says so.)
Add chips and watch the two readouts move together. Each step up the chips-per-bit row adds about 3 dB of processing gain — 8.5, 11.8, 14.9, 18.0, 21.0 dB for 7 through 127 chips — and the post-despread J/S falls by the same amount. At 127 chips and J/S = +10 dB the post-despread J/S is −11.0 dB and the peaks stand clear of the floor.
Push J/S past the gain. With 31 chips the processing gain is 14.9 dB, so the post-despread J/S crosses 0 dB when the jammer reaches about +15 dB. Take it past that and the bits start failing with the right code and perfect timing — the tile turns red, the dump dots turn red. Processing gain is a finite budget, not immunity. Add chips and the same jammer becomes survivable again.
Key observations#
Despreading is correlation. There is no filter in the receiver — just a multiply by the code and a sum over one bit. The bit “reappears” because \(N\) chip products all come out with the same sign and add coherently; everything else in the stream adds incoherently.
The jammer is never removed — it is spread thin. The correlator does not attenuate the jammer; it scatters the jammer’s power across the code’s bandwidth while gathering the signal’s power into one number. What changes is the ratio, and only by \(G_p\).
Wrong time is as bad as wrong code. A receiver holding the correct key but slipped one chip recovers nothing at all. That is why a real DSSS receiver spends its first effort on acquisition and then never stops tracking — staying on the peak is a continuous job, not a one-time alignment.
More chips buy gain at 3 dB per doubling. \(G_p = 10\log_{10} N\), so every doubling of the chip rate is worth 3 dB against the jammer — and the same length is what keeps two codes distinguishable from each other.
Source#
MATLAB bundle · L16_DSSSCorrelator.m↓
The companion script builds the same bits, m-sequence codes, tone jammer and sliding correlator, plots the correlator output for the right and the wrong code, and prints the peak correlation and the bits recovered for each.