Skip to content

PCM Frame Structure

The PCM (Pulse Code Modulation) telemetry system converts analog sensor readings and digital status words from the spacecraft into a serial bit stream. This stream is organized into fixed-length frames, each beginning with a sync word that lets the ground station find the frame boundaries in the raw data. Understanding the frame structure is essential for interpreting anything the spacecraft sends.

Frame formats, sync word structure, and A/D converter specifications are from the NAA Telecommunication Systems Study Guide (Course A-624). AGC channel assignments are from the Virtual AGC project.

Each high-rate frame contains exactly 128 eight-bit words, for a total of 1024 bits. The first four words (32 bits) are the sync word. The remaining 124 words carry telemetry data.

block-beta
    columns 8

    block:sync:4
        s1["Word 1"] s2["Word 2"] s3["Word 3"] s4["Word 4"]
    end
    block:data:4
        d1["Word 5"] d2["..."] d3["..."] d4["Word 128"]
    end

    style sync fill:#5c3a1a,stroke:#bd7a3a
    style data fill:#1a3a5c,stroke:#3a7abd

At the high bit rate of 51,200 bps, each 1024-bit frame takes exactly 20 milliseconds to transmit. Fifty of these frames make up one subframe, which spans exactly one second.

The 32-bit sync word is not a simple fixed pattern. It encodes four distinct fields:

block-beta
    columns 32
    block:a:5
        a1["A field<br/>5 bits"]
    end
    block:core:15
        c1["Fixed Core<br/>15 bits"]
    end
    block:b:6
        b1["B field<br/>6 bits"]
    end
    block:fid:6
        f1["Frame ID<br/>6 bits"]
    end

    style a fill:#2d5016,stroke:#4a8c2a
    style core fill:#5c3a1a,stroke:#bd7a3a
    style b fill:#2d5016,stroke:#4a8c2a
    style fid fill:#1a3a5c,stroke:#3a7abd
FieldBitsDefault ValuePurpose
A510101Patchboard-selectable identifier
Core15111001101011100Fixed correlator pattern (complemented on odd frames)
B6110100Patchboard-selectable identifier
Frame ID61-50Frame number within subframe

The A and B fields were configurable via patchboard on the actual spacecraft hardware — they served as a mission identifier, letting the ground station distinguish between multiple spacecraft transmitting on similar frequencies. gr-apollo uses the default values from the study guide.

The Frame ID counts from 1 to 50 within each subframe. This is how the ground station knows which frame it is looking at within the one-second subframe cycle.

The 15-bit fixed core is bitwise complemented on odd-numbered frames. On even frames (2, 4, 6, …, 50), the core bits are 111001101011100. On odd frames (1, 3, 5, …, 49), they become 000110010100011.

This alternation serves two purposes:

  1. DC balance. If the core never changed, the sync word would have a persistent DC bias that could cause baseline wander in the NRZ bit stream. Alternating between the pattern and its complement ensures the long-term average is near zero.

  2. Frame counting verification. The ground station can confirm it has not gained or lost a frame by checking whether the core matches the expected polarity for the current frame ID. If the polarity disagrees with the frame count, something has slipped.

Finding frame boundaries in a continuous bit stream is a three-phase process. The FrameSyncEngine implements a state machine:

stateDiagram-v2
    [*] --> SEARCH
    SEARCH --> VERIFY : Sync match found<br/>(Hamming distance <= 3)
    VERIFY --> LOCKED : N consecutive hits<br/>at frame boundaries
    VERIFY --> SEARCH : Miss at expected boundary
    LOCKED --> LOCKED : Hit at frame boundary
    LOCKED --> SEARCH : M consecutive misses

    note right of SEARCH
        Sliding 32-bit window
        checks every bit position
    end note

    note right of VERIFY
        Candidate found,
        waiting to confirm
        at next frame boundary
    end note

    note right of LOCKED
        Stable lock,
        emitting frames
    end note

SEARCH — The engine slides a 32-bit window across the incoming bits one bit at a time. At each position, it correlates the window contents against both the even and odd reference patterns (the 26 static bits — A + core + B). When the Hamming distance falls within the threshold, the engine has a candidate.

VERIFY — One match is not enough. Noise could produce a false trigger. The engine waits for the next frame boundary (1024 bits later at high rate) and checks whether another valid sync word appears there. After the configured number of consecutive hits at expected boundaries (default: 2), it transitions to LOCKED.

LOCKED — The engine is confident it has found the correct frame alignment. It emits complete frames as PDUs. If noise corrupts a sync word, the engine tolerates it and keeps going. Only after multiple consecutive misses at frame boundaries (default: 3) does it give up and return to SEARCH.

The sync word has 26 static bits (the A, core, and B fields). The frame ID changes every frame, so the correlator ignores it. A random 26-bit sequence has an expected Hamming distance of 13 from any reference pattern. Allowing up to 3 bit errors gives a comfortable margin:

  • Probability of false trigger (random data matching within distance 3 of a 26-bit pattern): approximately 1 in 4,000. At 51,200 bits per second, this means a false trigger roughly every 80 milliseconds — which is why the VERIFY state exists. Two false triggers landing exactly 1024 bits apart is astronomically unlikely.

  • Probability of missed detection (a real sync word with more than 3 errors): at typical operating SNR, the bit error rate is well below 10^-3, making 4 or more errors in the 26 static bits extremely rare.

The 124 data words (positions 5-128) carry three types of measurements:

Most data words are high-level analog measurements. The spacecraft’s A/D converter (the “coder”) samples 0-5V sensor outputs with 8-bit resolution.

The mapping is not quite what you would expect from a standard ADC:

CodeVoltageMeaning
0Below range (error)
10.00 VZero reference
20.0197 VFirst real step
1272.48 VMidscale
2544.98 VFull scale
255> 5.0 VOverflow

The step size is 19.7 mV per LSB, calculated as 4.98V / 253 steps. Code 0 and code 255 are reserved as boundary indicators, leaving 253 actual measurement levels from code 1 to code 254.

Three word positions within each frame have special significance for computer telemetry:

Word PositionAGC ChannelOctalRole
34DNTM1034Telemetry word high byte (bits 14-8)
35DNTM2035Telemetry word low byte (bits 7-0)
57OUTLINK057Additional digital downlink data

The Apollo Guidance Computer uses 15-bit words internally. Since the PCM system works in 8-bit bytes, each AGC word is split across two consecutive frame positions. Word 34 carries the upper 7 bits (bits 14 through 8) in its lower 7 bits. Word 35 carries the lower 8 bits (bits 7 through 0) directly.

Reassembly is straightforward:

agc_word = ((dntm1_byte & 0x7F) << 8) | dntm2_byte

At 50 frames per second, this means 50 AGC words per second arrive through the telemetry channel. The AGC buffers 400 words into each downlink list snapshot (taking about 8 seconds at high rate), then transmits the buffer contents as a coherent block of navigation state, autopilot settings, or other mission-phase-specific data.

The PCM system supports two bit rates, selectable by ground command. The choice affects frame size, frame rate, and the amount of data per second:

ParameterHigh RateLow Rate
Bit rate51,200 bps1,600 bps
Clock divider512 kHz / 10512 kHz / 320
Words per frame128200
Frames per second501
Words per second6,400200
Subframe period1 second (50 frames)N/A
Bits per frame1,0241,600
Frame period20 ms1 second

Low rate was used during translunar coast and other quiet phases where the Deep Space Network antenna time was shared between missions. High rate was used during critical mission phases — launch, lunar orbit insertion, powered descent, EVA — where dense telemetry coverage was essential.

At high rate, 50 consecutive frames form one subframe spanning exactly one second. The subframe concept matters because some telemetry measurements are commutated — they appear in different word positions across different frames within the subframe.

For example, a temperature sensor might be assigned to word position 72 in frame 3 of each subframe, while a pressure sensor occupies word 72 in frame 4. The same word position carries different physical measurements depending on which frame within the subframe you are looking at.

The frame ID field in the sync word (values 1 through 50) tells you which frame you are in, enabling the ground station software to route each word to the correct telemetry parameter.

graph LR
    subgraph Subframe ["Subframe (1 second)"]
        F1["Frame 1<br/>ID=1, odd"] --> F2["Frame 2<br/>ID=2, even"]
        F2 --> F3["Frame 3<br/>ID=3, odd"]
        F3 --> F4["..."]
        F4 --> F50["Frame 50<br/>ID=50, even"]
    end

    style Subframe fill:#1a1a2e,stroke:#3a7abd
    style F1 fill:#5c3a1a,stroke:#bd7a3a
    style F2 fill:#1a3a5c,stroke:#3a7abd
    style F3 fill:#5c3a1a,stroke:#bd7a3a
    style F50 fill:#1a3a5c,stroke:#3a7abd

The alternating colors reflect the complement-on-odd behavior of the sync core: odd frames (1, 3, 5, …) use the complemented pattern, even frames (2, 4, 6, …) use the normal pattern.