3 Commits

Author SHA1 Message Date
LittleSam129
f0fa7e8a46 Lab043: validate pilot-aided short BPSK link 2026-08-19 18:14:13 +03:00
LittleSam129
fce14f038e Lab042: transmit an image over the air, add the air loopback mode
First transmission through a real radio path in the project. A 4756-byte
JPEG went from transmitter to receiver over two antennas 60 cm apart at
225 MHz and reassembled byte-identical, reproduced across three runs.

The cable loopback still needs an SMA male-to-male adapter that has not
arrived, so this air run is a track verification, not the controlled
measurement: room levels are not held the way a cable holds them. Its
purpose was to exercise the device wrapper the models cannot cover.

Four defects the software model passed but the hardware exposed, each
reproduced and fixed:

- a 566 528-sample frame did not fit the 262 144 receive buffer, and the
  sample stream is not continuous across separate reads, so a frame on the
  seam was destroyed. Reception now uses one buffer sized to the frame
- carrier correction was always applied, but with a shared reference the
  true offset is near zero and the 80-symbol marker estimate is noise;
  correcting by it rotated phase along the whole frame, 65% bit errors
  measured. Ported should_apply_cfo_correction from Lab023
- receiver gain of 20 dB left the signal at 0.0003 of full scale. Levels
  set by measurement: RX 50 dB, TX -10 dB give zero bit errors with margin
- the error-vector metric returned zero on a failed receive, reporting a
  perfect signal where there was none, the same class of defect as the
  written-in figures of Lab041. Replaced with an explicit not-computed value

The air TX gain ceiling is now derived from the link budget by antenna
distance rather than a constant. Three loopback modes: software, cable,
air. PROJECT_LOG entry 019 records the run and the defects.

Software and cable results stay reproducible; 125 tests pass, gate passes.
2026-08-17 11:50:04 +03:00
LittleSam129
c9569164e0 Add protocol/bpsk_radio: reusable BPSK radio primitives
Lab042 cannot reuse the DSP from the earlier labs the way its
specification assumed. Three blockers turned up on inspection:

- importing lab018, lab019 or lab023 creates directories and writes .npy,
  .png and report files at module level, so importing them silently
  re-runs their experiments
- build_radio_frame() takes no arguments and encodes a fixed text message
- decode_radio_frame() returns a status string rather than the payload

So the verified primitives move into a module that is safe to import and
does no work of its own. Function bodies are carried over verbatim, and
the source lab is named above each one:

- from Lab023: bytes_to_bits, bits_to_bytes, bpsk_modulate,
  bpsk_demodulate, estimate_carrier_parameters, correct_phase_and_frequency
- from Lab019: build_frame_marker, find_radio_frame
- from Lab018: root_raised_cosine_taps

build_radio_frame and parse_radio_frame are written fresh here to carry
arbitrary payloads; the on-air structure is unchanged, still preamble,
sync word, length, packet.

Verified against the originals by loading their function definitions in
isolation and comparing outputs: 31 comparisons, no divergence, including
the CFO estimator over random phase and frequency offsets.

End-to-end check with no hardware: a 5828-byte JPEG through fragments,
packets, frames, shaping at 128 samples per symbol and matched filtering
recovers 12 of 12 fragments and reassembles byte-identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 14:16:32 +03:00