aethersdr / aethersdr/AetherSDR

HL2 spike: RX IQ sideband is inverted vs AetherSDR's convention (conjugate needed) — spike's WWV-at-DC validation cannot detect it

Open
#4,265 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

audio bug maintainer-review spectrum
Dominant language
C++
Stars
221
Forks
117
Avg merge
2d 7h
Merged PRs (30d)
299

Description

Following up on #4171 with a field finding from a second HPSDR radio, plus a bug I think Hl2RxDsp will hit in Phase 1c.

(Filing as a plain issue rather than via the bug template — that template asks for an AetherSDR release version and a SmartSDR radio/firmware string, neither of which applies to a finding about the prototypes/hl2/ spike.)

Context: I maintain Aether-gate (GPL-3.0), a radio→Flex bridge. I ported the spike's prototypes/hl2/hpsdr.py primitives into it to run a Radioberry (also HPSDR Protocol-1). The register-writing functions in my port are byte-for-byte identical to the spike's — cc_config, cc_rx1_freq, cc_rx_gain, ep2_packet, metis_command. The spike's data plane is solid, and CONFIG_MERCURY was exactly the gotcha you documented. Thank you for writing that down.

Two things worth having before 1a/1c.

1. The RX IQ sideband is inverted vs AetherSDR's convention

Feeding the spike's IQ into a real demod chain, signals paint on the wrong side of centre and FT8 does not decode. Fix is a conjugate at decode:

buf.append(complex(i, -q))   # HPSDR IQ sideband is inverted vs AE's convention

Verified live: signals then sit correctly under the passband indicator and the waterfall aligns. (50c6f7a)

I'm not claiming the spike is wrong — for its stated goal it's correct. I'm flagging that its validation method cannot detect this class of error, so the fact won't carry into Hl2RxDsp:

  • spectrum.py:67 builds np.array(I) + 1j*np.array(Q) — no conjugate.
  • panadapter() does fftshift(fft(x*w)) then np.abs(X). A magnitude spectrum is symmetric about DC, so conjugating the input yields pixel-identical output.
  • The validation signal is WWV at exactly 10 MHz, tuned to land at baseband DC (tune.py --freq 10000000, README phase 0.3/0.4).

An AM carrier at zero offset, viewed through a magnitude FFT, looks the same either way. Sideband inversion only becomes visible on an asymmetric signal, off-centre, through a demodulator — which is precisely what 1c adds. The design note's §5 Gap-B plan has Hl2RxDsp emitting QVector<float> dBm bins and 24 kHz PCM; both will be mirrored without the conjugate. Cheapest guard: tune WWV off-centre (e.g. NCO 10.001 MHz) and confirm the carrier appears on the correct side, or check any SSB signal is intelligible rather than inverted.

2. The Radioberry is an HL2 on the wire — Phase 1 likely covers it for free

Metis discovery against my Radioberry today:

raw[0:16] : ef fe 02 00 01 02 03 04 05 49 06 00 ...
MAC       : 00:01:02:03:04:05
gateware  : 0x49 = 73  -> v7.3
board id  : 0x06          <- same as Hermes-Lite 2

It reports board id 0x06 and speaks the same register set — identical code drives both. So Hl2Backend should need no Radioberry special-casing, which I think modestly strengthens the §5 Gap-A argument: the selection seam buys a second radio family at zero marginal cost.

Two small compatibility notes if useful:

  • Fake MAC (00:01:02:03:04:05, sequential, not a real OUI). Anything keying device identity off the discovery MAC will collide with two Radioberrys on one LAN.
  • Gateware 7.3 vs the spike's 7.4, no functional difference in the three registers used — but a >= 7.4 gate would exclude the Radioberry for no reason.

Happy to test Phase 1 against the Radioberry when there's something to run. All facts above are from live black-box observation of my own hardware.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with prototypes/hl2/spectrum.py, tune.py, and the README validation steps, then read the Phase 1c Hl2RxDsp plan and design note §5 Gap-B. Validate the sideband with an off-centre signal or asymmetric SSB rather than a magnitude-only DC test, and confirm that the resulting bins and PCM are not mirrored. Check the board-id and gateware assumptions against the reported Radioberry discovery data.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
audio-video-rtc, embedded-iot, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.