Dit project is opgezet voor experimenten waarbij het NICAM DQPSK-signaal direct op RF wordt gezet, dus zonder analoge TV-draaggolf/subcarrierketen. De huidige keten bevat een echte NICAM 728 payload encoder/decoder, een standalone C-zender voor PlutoSDR en een standalone C-ontvanger voor live RTL-SDR ontvangst.
Voor NICAM zijn de normale TX/RX-paden volledig C-gebaseerd:
nicam-pluto-tx voor PlutoSDR TX en nicam-rx voor RTL-SDR RX. De aparte WBFM
TX/RX-paden en sommige ontwikkel- of analysetools gebruiken Python.
- NICAM bitrate:
728 kbit/s - DQPSK symbolrate:
364 ksym/s - Praktische RF-bandbreedte (deze implementatie): ongeveer
500-750 kHz - Frame:
728 bits, dus1 ms - FAW:
01001110 - Scrambler: PN9, polynomial
x^9 + x^4 + 1, seed111111111 - Audio: stereo, 32 kHz, NICAM 728 near-instantaneous companding
- Direct-QPSK mode: stem de RTL-SDR af op de NICAM RF-carrier zelf
- NICAM baseband sample-rate:
1456000samples/s, precies 4 samples per DQPSK-symbool - Pluto/IIO TX device sample-rate: automatisch gekozen of ingesteld met
NICAM_TX_DEVICE_SAMPLE_RATE; de NICAM timing blijft intern1456000
De normale entry points zijn:
tools/tim-nicam-tx: NICAM TX via PlutoSDR/libiiotools/websdr-nicam-rx: NICAM RX via RTL-SDRtools/tim-wbfm-tx: optionele WBFM TX, Python-gebaseerdtools/websdr-wbfm-rx: optionele WBFM RX, Python-gebaseerd
Voor live gebruik op de Odroid is er een standalone C-programma met de naam
nicam-rx:
- stdin:
rtl_sdr-achtige unsigned 8-bit IQ (I,Q,I,Q,...) - stdout: raw stereo
s16leaudio op32 kHz - stderr: lock/statusmeldingen bij
--verbose
Standaard verwacht ./nicam-rx rtl_sdr-compatibele u8 IQ. Voor andere SDR
hardware of offline bestanden kan ook interleaved signed 16-bit IQ worden
gelezen:
./nicam-rx --iq-format s16 --sample-rate 1456000 < input.cs16 > output.pcmCompileren van de C-ontvanger:
makeDit bouwt:
./nicam-rxDe Makefile gebruikt alleen een C compiler en libm. Op Debian/Ubuntu/Odroid:
sudo apt install build-essential rtl-sdr alsa-utils
makeCompileren van de PlutoSDR C-zender:
sudo apt install build-essential libiio-dev ffmpeg
tools/build-nicam-pluto-txDit bouwt:
./nicam-pluto-txDe zender gebruikt libiio voor PlutoSDR/AD9361 toegang. Voor normale TX op
tim verwacht tools/tim-nicam-tx dat ./nicam-pluto-tx al gebouwd is.
De C-code is gewone C11 en bevat geen x86-specifieke intrinsics. Hij is bedoeld
om ook op ARM64/Odroid te compileren met gcc of clang.
Live luisteren met RTL-SDR en ALSA:
rtl_sdr -f 54552000 -s 1456000 -g 29.7 - \
| ./nicam-rx --sample-rate 1456000 --verbose \
| aplay -f S16_LE -r 32000 -c 2Met een LO van 48 MHz en een NICAM subcarrier op 6.552 MHz is de gewenste
RTL-SDR frequentie:
48.000 MHz + 6.552 MHz = 54.552 MHz
Als je liever via ffplay luistert:
rtl_sdr -f 54552000 -s 1456000 -g 29.7 - \
| ./nicam-rx --sample-rate 1456000 --verbose \
| ffplay -hide_banner -loglevel error -nodisp \
-f s16le -sample_rate 32000 -ch_layout stereo -i -Voor het upconverter-testplan:
- Digital Baseband NICAM op
6.552 MHz - LO op
48 MHz - 50-70 MHz filter na de mixer
- RTL-SDR op
54.552 MHz
De C-decoder is getest tegen referentie-IQ-bestanden. Op een 30 seconden 10 dB
SNR testbestand decodeerde ./nicam-rx ongeveer in real-time factor 30 sneller
dan nodig.
De normale NICAM TX/RX-launchers starten de C-programma's ./nicam-pluto-tx en
./nicam-rx. Voor NICAM is dus een C compiler nodig plus de tools/libraries van
de gebruikte SDR.
NICAM TX-host met PlutoSDR/AD9361:
sudo apt install build-essential ffmpeg libiio-dev
tools/build-nicam-pluto-txDit bouwt ./nicam-pluto-tx. De zender gebruikt ffmpeg alleen om stream-,
file- of UDP-audio naar raw stereo s16le op 32 kHz om te zetten.
NICAM RX-host met RTL-SDR:
sudo apt install build-essential rtl-sdr alsa-utils
makeDit bouwt ./nicam-rx. alsa-utils is nodig wanneer je via aplay luistert;
voor ffplay playback installeer je ook ffmpeg.
Lokale machineprofielen maak je uit de examples:
cp config/environments/tim.env.example config/environments/tim.env
cp config/environments/websdr.env.example config/environments/websdr.envCommit deze lokale .env bestanden niet.
De Python requirements horen bij de aparte WBFM Python-zender/ontvanger en bij
het direct starten van Python modules uit src/wbfm_*. Sla deze WBFM-stap over
wanneer je alleen de C-binaries ./nicam-pluto-tx en ./nicam-rx gebruikt.
Optie A voor WBFM: user-installatie (zonder venv):
python3 -m pip install --user -r requirements.txt
python3 -m pip install --user -e .Optie B voor WBFM: virtual environment (venv):
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
pip install -e .Voor de NICAM launchers (tools/tim-nicam-tx en tools/websdr-nicam-rx) zijn
de C-binaries ./nicam-pluto-tx en ./nicam-rx bepalend. De WBFM launchers
gebruiken wel Python via tools/nicam-run.
Voor NICAM RX is ./nicam-rx de enige ondersteunde decoder. Live luisteren via
RTL-SDR loopt via de host-launcher:
NICAM_RX_GAIN=29.7 NICAM_RX_MATCHED_FILTER=1 tools/websdr-nicam-rxEen opgeslagen IQ-bestand terugluisteren:
./nicam-rx --sample-rate 1456000 --matched-filter < /tmp/radio2-nicam.iq \
| aplay -f S16_LE -r 32000 -c 2Belangrijke live-opties:
--freq: frequentie van de directe NICAM QPSK carrier in Hz--ppm: RTL-SDR correctie--gain: tuner gain, ofauto--sample-rate: standaard1456000--iq-in: lees IQ uit een bestand in plaats van live vanrtl_sdr--matched-filter: gebruik het RRC matched filter bij RRC-vormgegeven TX
Voor end-to-end testen kan de C-zender audio naar echte NICAM 728 payloads
encoderen en daarna naar direct-QPSK IQ moduleren. Met --iq-out schrijft hij
een rtl_sdr-achtige unsigned 8-bit IQ-stream naar een bestand in plaats van
naar PlutoSDR.
Een testtoon naar direct-QPSK IQ moduleren:
./nicam-pluto-tx --source tone --seconds 5 --iq-out /tmp/nicam-tone.iqNICAM carrier level kan op dezelfde schaal als de PE1MUD/PE1OBW Digital Baseband worden gezet:
./nicam-pluto-tx --source tone --nicam-rf-level 200 --seconds 5 --iq-out /tmp/nicam.iqHierbij is 200 ongeveer -14.2 dBFS, want:
20 * log10(200 / 1023) = -14.2 dB
Een internetstream naar een IQ-bestand moduleren:
ffmpeg -hide_banner -loglevel error -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 \
-i "https://icecast.omroep.nl/radio2-bb-aac" -vn -f s16le -ac 2 -ar 32000 - \
| ./nicam-pluto-tx --source pcm --pcm-in - --seconds 30 --iq-out /tmp/radio2-nicam.iqMet de C-decoder kun je hetzelfde IQ-bestand terugluisteren:
./nicam-rx --sample-rate 1456000 --matched-filter --verbose < /tmp/radio2-nicam.iq \
| aplay -f S16_LE -r 32000 -c 2Voor live zenden draait de C-zender met een doorlopende TX-clock. De launcher kan audio uit een internetstream, bestand, UDP raw PCM, toon of stilte halen. Bij PCM-bronnen gebruikt de C-zender een korte timeout; als de bron tijdelijk niets levert, blijft de NICAM-keten stilte en frames/IQ-samples doorsturen.
Normaal starten op tim met de profieldefaults:
tools/tim-nicam-txDigital Baseband V1.4-compatible station-ID in de NICAM additional-data bits:
NICAM_TX_STATION_ID=PE1ITR tools/tim-nicam-txAlleen de eerste 8 ASCII-tekens worden gebruikt. De mapping is:
AD0..AD2 = tekenpositie 0..7, AD3..AD10 = ASCII-teken.
Een bron via UDP naar de zender sturen:
NICAM_TX_SOURCE=udp NICAM_TX_UDP_URL=udp://0.0.0.0:7355 tools/tim-nicam-tx
ffmpeg -hide_banner -loglevel error -re -i input \
-vn -ac 2 -ar 32000 -f s16le \
'udp://zender-ip:7355?pkt_size=1024'Belangrijk:
- Gebruik
-reof een bron die zelf op audioclock uitstuurt. Zonder pacing kan UDP-audio bursty aankomen en moet de zenderbuffer samples droppen. - UDP-audioformaat voor NICAM is raw stereo
s16leop32 kHz. - Bij
NICAM_TX_SOURCE=udpleesttools/tim-nicam-txraw stereos16leaudio viaffmpegen voert dat aan de C-zender. - De C-zender gebruikt standaard root-raised-cosine pulse shaping met
NICAM_TX_PULSE_ROLLOFF=0.4enNICAM_TX_PULSE_SPAN_SYMBOLS=6.
De relevante profieldefaults staan in config/environments/tim.env.example:
NICAM_TX_SOURCE=stream
NICAM_TX_STREAM_URL=https://icecast.omroep.nl/radio2-bb-aac
NICAM_TX_UDP_URL=udp://0.0.0.0:7355
NICAM_TX_CONNECT_MODE=network
NICAM_TX_IP=192.168.2.1
NICAM_BASEBAND_SAMPLE_RATE=1456000
NICAM_TX_DEVICE_SAMPLE_RATE= # leeg = auto
NICAM_TX_PULSE_SHAPE=1
NICAM_TX_PULSE_ROLLOFF=0.4
NICAM_TX_PULSE_SPAN_SYMBOLS=6Referentiemetingen uit de C TX/RX loop-test:
-
C TX/RX bit-error sweep, SNR
0..14 dBin stappen van0.5 dB. Per meetpunt zijn10,000NICAM-frames getest (7,280,000bits). Bad frames en gemiste frames tellen mee als bitfouten. In deze meting wordt de keten bruikbaar rond6.5-7 dBSNR en vrijwel foutloos vanaf ongeveer8.5-10 dB. -
C TX-spectrum van dezelfde PRBS-bron, relatieve schaal. Dit laat zien wat je van de RRC-vormgegeven directe DQPSK TX verwacht in een
1.5 MHzspan.
De kleine meetplots en CSV-bestanden onder artifacts/ horen bij de
documentatie. Grote ruwe testbestanden zoals *.u8iq, *.pcm en *.npy
blijven buiten git.
De native C-zender stuurt direct naar PlutoSDR via libiio:
tools/build-nicam-pluto-tx
./nicam-pluto-tx --lo 100000000 --tx-gain -30 --source toneMet een audiostream:
tools/tim-nicam-txBelangrijke Pluto-opties:
--lo: RF-carrier in Hz--connect-mode:network,usbofauto; standaardnetwork--ip: netwerkadres bij--connect-mode network, standaard192.168.2.1--usb-uri: USB URI bij--connect-mode usb, standaardusb:--baseband-sample-rate: logische NICAM sample-rate, standaard1456000--tx-sample-rate: Pluto/IIO device sample-rate; standaard auto--uri: handmatige libiio URI override, bijvoorbeeldip:192.168.2.1--tx-gain: Pluto TX hardware gain/attenuation in dB, begin laag, bijvoorbeeld-40tot-30--rf-bandwidth: standaard750000--source:tone,silenceofpcm--pcm-in: raw stereos16leaudio op32 kHz, of-voor stdin--iq-out: schrijf test-IQ naar bestand in plaats van Pluto TX
Er worden twee PlutoSDR-achtige TX-paden ondersteund:
- ADALM-Pluto/PlutoSDR firmware die de native NICAM-rate
1456000samples/s op de IIO TX-stream accepteert. De zender gebruikt dan automatisch die lage device sample-rate, zodat de USB/netwerkstream zo licht mogelijk blijft. - Pluto-achtige firmware die
1456000weigert of alleen een bereik meldt, zoals[2083333 1 61440000]. De NICAM timing blijft intern1456000, maar de zender resamplet de uiteindelijke complex baseband stream naar een werkende Pluto/IIO sample-rate.
In auto-mode kiest de software eerst de native 1456000 als die echt wordt
geaccepteerd. Als die rate door de driver wordt geweigerd, valt hij terug naar
een lagere bruikbare device-rate. Voor de huidige Rev.B/Rev.C Pluto-tests met
rangevorm [2083333 1 61440000] is de automatische fallback 2184000
samples/s, met resampler-ratio 3/2. Dit bleek stabieler en lichter dan
3840000. Handmatig is 2730000 (15/8) aan de TX-kant mooi stabiel getest.
Hogere rates zoals 2912000 (2/1), 3276000 (9/4) en vooral 3840000
(240/91) zitten dichter tegen de USB/libiio transportlimiet en moeten per
setup opnieuw worden beoordeeld.
Praktisch getest aan de TX-kant:
- Analog Devices PlutoSDR Rev.B (
Z7010-AD9364), via USB/libiio. Deze Pluto rapporteerde een rangevormsampling_frequency_available: [2083333 1 61440000];1456000werd door de driver geweigerd. Auto valt daarom terug naar2184000en resamplet1456000 -> 2184000met ratio3/2. - Analog Devices PlutoSDR Rev.C / OpenSourceSDRLab Pluto-compatible
(
Z7020-AD9361), via USB/libiio. Stabiel getest met auto op2184000en handmatig metNICAM_TX_DEVICE_SAMPLE_RATE=2730000. Dat is op deze hardware de hoogste rate waarmee tot nu toe mooie stabiele resultaten zijn gezien. - Dezelfde Rev.C / OpenSourceSDRLab hardware via 100 Mbit Ethernet/libiio is
functioneel bereikbaar, maar de
iio_buffer_pushtransporttijd was in de praktijk te hoog voor stabiele realtime TX. USB gaf duidelijk betere resultaten.
De standaard launcher gebruikt netwerk:
NICAM_TX_CONNECT_MODE=network \
NICAM_TX_IP=192.168.2.1 \
NICAM_TX_SOURCE=stream \
NICAM_TX_STATION_ID=PE1ITR \
NICAM_TX_GAIN_DB=-6 \
NICAM_TX_AMPLITUDE=3.0 \
NICAM_TX_RF_BANDWIDTH=1750000 \
tools/tim-nicam-txVia USB:
NICAM_TX_CONNECT_MODE=usb \
NICAM_TX_USB_URI=usb: \
NICAM_TX_SOURCE=stream \
NICAM_TX_STATION_ID=PE1ITR \
NICAM_TX_GAIN_DB=-6 \
NICAM_TX_AMPLITUDE=3.0 \
NICAM_TX_RF_BANDWIDTH=1750000 \
tools/tim-nicam-txLaat NICAM_TX_DEVICE_SAMPLE_RATE normaal leeg. De zender leest
sampling_frequency_available, probeert waar zinvol 1456000, en valt anders
terug op een ondersteunde hogere TX-rate zoals 2184000. Expliciet forceren kan
met:
NICAM_TX_DEVICE_SAMPLE_RATE=2730000 tools/tim-nicam-txDe startup-log meldt altijd de NICAM baseband sample-rate, de gekozen Pluto/IIO
TX sample-rate, de resampler-ratio, RF-bandbreedte, connect mode en resolved IIO
URI. Bij performanceonderzoek print de zender ook profile_ms_per_buffer, waar
push de libiio/transporttijd is.
Voor een korte offline test kun je eerst IQ maken:
./nicam-pluto-tx --source tone --seconds 1 --iq-out /tmp/nicam-tone.iq
./nicam-rx --sample-rate 1456000 --matched-filter < /tmp/nicam-tone.iq > /tmp/nicam-tone.pcmNaast de directe NICAM/QPSK-keten bevat het project ook een experimentele stereo WBFM-zender voor PlutoSDR. Deze maakt een FM-MPX-signaal met L+R, 19 kHz pilot en L-R DSB-subcarrier, moduleert dat naar complex baseband IQ en kan dit direct naar de Pluto sturen.
De standaardinstellingen staan in config/config.yaml. Test eerst offline of de
audio-naar-IQ-keten werkt:
PYTHONPATH=src python3 -m wbfm_tx.main \
--config config/config.yaml \
--source wav \
--input test_audio/voorbeeld.wav \
--iq-out /tmp/wbfm.complex64 \
--seconds 2Uitzenden via PlutoSDR:
PYTHONPATH=src python3 -m wbfm_tx.main \
--config config/config.yaml \
--freq 2323.7 \
--gain -30 \
--source wav \
--input test_audio/voorbeeld.wav \
--cyclicNa een editable install kun je ook wbfm-tx gebruiken in plaats van
python3 -m wbfm_tx.main.
Belangrijke WBFM-opties:
--freq: Pluto TX LO in MHz--gain: Pluto TX hardware gain in dB; begin laag--source:wav,stream,deviceofsilence--iq-out: schrijf complex64 baseband IQ naar een bestand in plaats van TX--deviation: FM-deviatie in Hz, standaard75000--preemphasis-us: pre-emphasis, standaard50--pilot-level: 19 kHz pilotniveau
De RTL-SDR WBFM-ontvanger decodeert standaard stereo broadcast-FM: FM discriminator, 19 kHz pilot, L-R subcarrier, 50 us de-emphasis en stereo PCM. De stereo-decoder gebruikt standaard gedeeltelijke stereo-blend om L-R-ruis te beperken.
Naar WAV opnemen:
PYTHONPATH=src python3 -m wbfm_rx.rtl_rx \
--device-index 1 \
--freq 100700000 \
--sample-rate 960000 \
--gain 29.7 \
--audio-out /tmp/wbfm-rx.wavLive luisteren met ffplay:
PYTHONPATH=src python3 -m wbfm_rx.rtl_rx \
--device-index 1 \
--freq 100700000 \
--sample-rate 960000 \
--gain 29.7 \
--audio-out - \
| ffplay -hide_banner -loglevel error -nodisp \
-f s16le -sample_rate 48000 -ch_layout stereo -i -Een offline WBFM IQ-bestand uit de zender terugdecoderen kan met:
PYTHONPATH=src python3 -m wbfm_rx.rtl_rx \
--iq-in /tmp/wbfm.complex64 \
--iq-format complex64 \
--audio-out /tmp/wbfm-loop.wavNa een editable install kun je ook wbfm-rx gebruiken in plaats van
python3 -m wbfm_rx.rtl_rx.
Bij ruis eerst mono vergelijken:
tools/websdr-wbfm-rx --monoDaarna stereo-blend instellen. Lager is rustiger, hoger is breder stereo:
tools/websdr-wbfm-rx --stereo-blend 0.35
tools/websdr-wbfm-rx --stereo-blend 1.0De ontvanger heeft standaard pilot-squelch. Als de zender wegvalt en de 19 kHz pilot onvoldoende is, fade't de audio dicht:
tools/websdr-wbfm-rx --verbose
tools/websdr-wbfm-rx --squelch-pilot 0.12
tools/websdr-wbfm-rx --no-squelchDe launchers lezen hostspecifieke defaults uit config/environments/. Voor
NICAM gebruiken tools/tim-nicam-tx en tools/websdr-nicam-rx deze profielen
voor SDR-instellingen, audio-routing en standaardfrequenties. Voor WBFM gebruikt
tools/nicam-run dezelfde profielen ook om de juiste Python-omgeving te kiezen.
Profielkeuze voor tools/nicam-run en de host-launchers:
tools/nicam-run wbfm-rx ...
NICAM_ENV=websdr tools/nicam-run nicam-rx ...
NICAM_ENV_FILE=/opt/nicam/local.env tools/nicam-run wbfm-tx ...Zonder override zoekt de launcher automatisch:
config/environments/$(hostname -s).envVoorbeeldprofielen staan in:
config/environments/websdr.env.exampleconfig/environments/odroid.env.exampleconfig/environments/desktop.env.exampleconfig/environments/user-install.env.example
Belangrijke profielvelden:
AUDIO_BACKEND=aplay # stdout, ffplay, aplay of none
AUDIO_DEVICE=plughw:0,0
NICAM_AUDIO_RATE=32000
WBFM_AUDIO_RATE=48000
PYTHON_MODE=src # alleen relevant voor WBFM/module starts: src, user of venv
PYTHON_BIN=python3
VENV_PATH=${REPO_DIR}/.venvVoorbeelden:
tools/nicam-run nicam-rx --device-index 1 --freq 435970000 --gain 29.7
tools/nicam-run wbfm-rx --device-index 1 --freq 100700000 --gain 29.7
tools/nicam-run wbfm-tx --config config/config.yaml --source stream --stream-url "https://icecast.omroep.nl/radio2-bb-aac"WebSDR/Odroid WBFM shortcut, met config/environments/websdr.env en standaard
436000000 Hz:
tools/websdr-wbfm-rxTijdelijk overschrijven:
GAIN=29.7 FREQ_HZ=436000000 tools/websdr-wbfm-rx
tools/websdr-wbfm-rx --monoTim WBFM-zender shortcut, met .venv en standaard 2324 MHz:
cp config/environments/tim.env.example config/environments/tim.env
tools/tim-wbfm-txTijdelijk overschrijven:
TX_GAIN_DB=-15 tools/tim-wbfm-tx
TX_FREQ_MHZ=2324 TX_STREAM_URL="https://icecast.omroep.nl/radio2-bb-aac" tools/tim-wbfm-txBij korte internetstream-haperingen blijft de WBFM-zender standaard doorlopen: ffmpeg reconnect wordt gebruikt, de decoder wordt opnieuw gestart bij EOF, en er wordt tijdelijk stilte uitgezonden. Uitzetten kan met:
tools/tim-wbfm-tx --no-stream-silence
tools/tim-wbfm-tx --no-stream-reconnectNICAM shortcuts:
tools/tim-nicam-tx
tools/websdr-nicam-rxDe NICAM zender op tim gebruikt standaard 2324 MHz en de NICAM ontvanger op
websdr gebruikt standaard 436 MHz IF. Tijdelijk overschrijven:
NICAM_TX_GAIN_DB=-8 tools/tim-nicam-tx
NICAM_TX_SOURCE=tone tools/tim-nicam-tx
NICAM_RX_GAIN=29.7 tools/websdr-nicam-rx
NICAM_RX_MATCHED_FILTER=1 tools/websdr-nicam-rxDe lokale configuratie bevat een operatorprofiel voor een volledige amateurvergunning op de amateurbanden:
operator:
amateur_radio_license: "full"
amateur_bands_authorized: true
suppress_tx_warnings: trueMet suppress_tx_warnings: true onderdrukt de WBFM-zender de generieke
TX-gain-waarschuwing. Voor labtests blijft een coaxverbinding met verzwakker
tussen Pluto en RTL-SDR het meest reproduceerbaar.
tools/nicam-run nicam-rx start rtl_sdr en pipe't de samples naar
./nicam-rx:
tools/nicam-run nicam-rx \
--freq 100000000 \
--gain 30 \
--matched-filter \
--verboseLive luisteren kan met ffplay:
AUDIO_BACKEND=ffplay tools/nicam-run nicam-rx \
--freq 100000000 \
--gain 30 \
--matched-filterAls de zender een Digital Baseband V1.4-compatible station-ID meestuurt, print
./nicam-rx de gestabiliseerde waarde op stderr als station_id=.... Met
--stats-every N staat dezelfde waarde ook in de periodieke nicam_stats regel.
JSON-statusupdates zijn apart instelbaar met --stats-json FILE en
--stats-json-every N.
Directe offline test van C-zender naar C-ontvanger:
./nicam-pluto-tx --source tone --seconds 5 --iq-out /tmp/nicam-loop.iq
./nicam-rx --sample-rate 1456000 --matched-filter --verbose < /tmp/nicam-loop.iq > /tmp/nicam-loop.pcmLive luisteren met ffplay:
./nicam-pluto-tx --source tone --seconds 5 --iq-out /tmp/nicam-tone.iq
./nicam-rx --sample-rate 1456000 --matched-filter < /tmp/nicam-tone.iq \
| ffplay -hide_banner -loglevel error -nodisp -f s16le -sample_rate 32000 -ch_layout stereo -i -Als er geen geluid uit ffplay komt, schrijf dan eerst een WAV-bestand om te
controleren of de modulator-demodulator-keten audio produceert:
./nicam-pluto-tx --source tone --seconds 3 --iq-out /tmp/nicam-tone.iq
./nicam-rx --sample-rate 1456000 --matched-filter --verbose < /tmp/nicam-tone.iq > /tmp/nicam-tone.pcm
ffplay -hide_banner -loglevel error -autoexit -f s16le -sample_rate 32000 -ch_layout stereo -i /tmp/nicam-tone.pcmMaak een synthetisch direct-DQPSK IQ-bestand met de C-zender:
./nicam-pluto-tx --source tone --seconds 1 --iq-out /tmp/nicam-test.iq
./nicam-rx --sample-rate 1456000 < /tmp/nicam-test.iq > /tmp/nicam-test.pcmsrc/nicam_tx/nicam_pluto_tx.c gebruikt libiio en verwacht dat de Pluto via USB
of netwerk bereikbaar is.
Voor een installatie waar de repo in ~/nicam staat:
mkdir -p ~/.config/systemd/user
cp ~/nicam/systemd/user/nicam-rx.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now nicam-rx.serviceFrequentie-instelling met converter:
- RF doelfrequentie:
2324 MHz - Externe converter LO:
1888 MHz - RTL-SDR tuningfrequentie (IF):
436 MHz(2324 - 1888 = 436)
Status en logs:
systemctl --user status nicam-rx.service
journalctl --user -u nicam-rx.service -fStandaard draait deze service via tools/websdr-nicam-rx, met
rtl_sdr -d 00000001 op 436000000 Hz.
Dit is bedoeld voor een externe converter met LO 1888 MHz voor een doelfrequentie
van 2324 MHz (2324 - 1888 = 436 MHz IF).
Extra C-decoderopties kun je via NICAM_RX_EXTRA_ARGS meegeven, bijvoorbeeld het
matched filter:
systemctl --user edit nicam-rx.serviceVoeg toe:
[Service]
Environment=NICAM_RX_EXTRA_ARGS=--matched-filter --verboseDaarna:
systemctl --user daemon-reload
systemctl --user restart nicam-rx.serviceUitzetten: verwijder deze Environment=NICAM_RX_EXTRA_ARGS=... regel weer (of maak hem leeg) en herstart de service.
Waar zie je het:
- In foreground/terminal: op
stderrvan./nicam-rx - Als systemd user-service: via
journalctl --user -u nicam-rx.service -f
Voorbeeldregel:
decoded_frames=29998
De C-ontvanger kan periodiek een machineleesbare status naar JSON schrijven:
NICAM_RX_STATUS_JSON=/var/www/html/nicam/nicam-rx-status.json \
NICAM_RX_STATUS_EVERY=2000 \
tools/websdr-nicam-rxtools/nicam-run maakt de directory aan en geeft dit door als
--stats-json ... --stats-json-every ... aan ./nicam-rx. De standaard in
config/environments/websdr.env.example schrijft naar:
/var/www/html/nicam/nicam-rx-status.json
De JSON bevat onder andere rx_status, signal_present, locked,
station_id, bad_frame_rate, slicer_conf, carrier_hz, omega, frame
counters en sync/drop counters. bad_frame_rate wordt over het recente locked
interval berekend en is null zolang de ontvanger niet locked is. De
statuspagina toont STOPPED wanneer de JSON ontbreekt of te oud is, IDLE
wanneer de ontvanger draait maar geen bruikbaar signaal ziet, en
LOCKED/UNLOCKED wanneer er wel signaalstructuur aanwezig is.
Voor een eenvoudig dashboard staat er een statische pagina in:
web/nicam-rx-status.html
Plaats deze pagina op de webserver van websdr en serveer het JSON-bestand als
nicam-rx-status.json naast de pagina, of geef een andere URL mee:
nicam-rx-status.html?status=/path/to/nicam-rx-status.json
De huidige websdr-default schrijft direct naar
/var/www/html/nicam/nicam-rx-status.json. Zorg dat deze directory bestaat en
schrijfbaar is voor de user waaronder de systemd user-service draait.
De huidige keten is bruikbaar voor live experimenten, maar de DQPSK-demodulator is nog een belangrijk verbeterpunt. Geplande RX-verbeteringen:
- Robuustere carrier-lock voor meer marge bij frequentie-offset en fase-ruis.
- Betere timing-lock/symbol timing recovery, vooral bij lagere SNR en minder ideale sampleclock.
- Verbetering van de QPSK slicer, inclusief evaluatie van soft-decision metrics in plaats van alleen hard decisions.
- Meer meetbare regressietests voor lockgedrag, bad-frame-rate en audio-uitval bij gecontroleerde SNR, offset en timingfouten.
- ETSI ETS 300 163 (NICAM 728, Nov 1994): https://www.etsi.org/deliver/etsi_i_ets/300100_300199/300163/01_60/ets_300163e01p.pdf
- ETSI EN 300 163 V1.2.1 (Mar 1998, catalogus): https://standards.iteh.ai/catalog/standards/etsi/60810122-7c6b-44ed-9196-311b7673a79c/etsi-ets-300-163-ed-1-1994-11
Dit project is gelicentieerd onder de Apache License, Version 2.0. Zie LICENSE.
Attributie is niet verplicht, maar bronvermelding naar Rob Hardenberg (PE1ITR) wordt gewaardeerd bij gebruik van deze software, metingen, plots of afgeleide resultaten in publicaties, presentaties, artikelen, video's of publieke projecten. Zie NOTICE.
De softwarelicentie geeft geen toestemming om buiten de geldende radio-, omroep-, spectrum- of typegoedkeuringsregels uit te zenden. Controleer voor praktisch RF-gebruik zelf de lokale regelgeving, vergunningen en bandplannen.
NICAM 728 is beschreven in ETSI EN 300 163. ETSI-documenten kunnen verwijzen naar verklaarde of mogelijk essentiele IPR's; ETSI voert daarbij zelf geen volledige patent-clearance uit. Deze repository bevat een experimentele implementatie en geeft geen garantie dat gebruik in een product, dienst of uitzending vrij is van rechten van derden.

