Hallo Habr.
Der
zweite Teil untersuchte die praktischen Aspekte der Verwendung von SZR. In diesem Teil werden wir uns ansehen, wie NOAA-Wettersatellitendaten mit Python und dem kostengünstigen (30 US-Dollar) RTL-SDR-Empfänger empfangen werden. Der betrachtete Code funktioniert überall - unter Windows, OSX, Linux und sogar auf dem Raspberry Pi.

Wen kümmert es, fuhr unter dem Schnitt fort.
SoapySDR
Es gibt eine ganze Reihe von Herstellern verschiedener SDR-Geräte, und es wäre sehr unpraktisch, jedes einzeln zu unterstützen, und es ist teuer, Hardware zum Testen zu kaufen. Grundsätzlich gibt es für den einheitlichen Zugriff zwei Bibliotheken, die im Wesentlichen zum Standard geworden sind. Die erste ist die ziemlich alte
ExtIO DLL- Schnittstelle, die wahrscheinlich nicht weniger als 10 Jahre alt ist, die zweite ist die modernere
SoapySDR- Bibliothek, die wir untersuchen werden.
SoapySDR ist eine Reihe plattformübergreifender Bibliotheken, die in C ++ geschrieben wurden und einen einheitlichen Zugriff auf SDR-Geräte, sowohl Empfänger als auch Transceiver, ermöglichen. Wenn der Hersteller eine solche Schnittstelle herstellt, arbeitet sein Gerät automatisch mit einer relativ großen Anzahl gängiger Programme (GQRX, GNU Radio, CubicSDR usw.). Mit Ausnahme einiger adäquater Hersteller
(bei dieser Gelegenheit sende ich meine Grüße an EE) haben SoapySDR-Unterstützung. Eine Liste der unterstützten Geräte finden Sie
auf der Projektseite . Wie Sie sehen können, ist es ziemlich groß und umfasst HackRF, USRP, SDRPlay, LimeSDR, RTL-SDR, Red Pitaya und viele andere.
Die SoapySDR-Bibliothek ist plattformübergreifend, d.h. Der dafür geschriebene Code funktioniert unter Windows, OSX, Linux und sogar auf dem Raspberry Pi. Für Windows sind die erforderlichen Bibliotheken Teil des
PothosSDR- Pakets, für andere Plattformen muss SoapySDR unabhängig kompiliert werden. Es ist notwendig, zwei Teile zu kompilieren - die
Bibliothek selbst und das „Plug-In“ für den gewünschten Empfänger. In unserem Fall handelt es sich um
SoapyRTLSDR (unter Windows kann die Bibliothek auch aus dem Quellcode zusammengestellt werden. Dazu benötigen Sie Visual Studio, Cmake und SWIG). Jetzt ist alles fertig und Sie können Code schreiben.
Wir importieren die Bibliothek und erhalten eine Liste der Empfänger:
from __future__ import print_function import SoapySDR
Wir verbinden den Empfänger, führen den Code aus und sehen eine Liste der Geräte, darunter unser rtlsdr.

Der Rest der Geräte sind Soundkarten, wie wir uns erinnern. Historisch gesehen arbeiteten die ersten SDRs genau über den linearen PC-Eingang, und die Bibliothek unterstützt sie auch. Wir erhalten Informationen über das Gerät - Anzahl der verfügbaren Kanäle, Frequenzbereich usw.:
soapy_device = "rtlsdr" device = SoapySDR.Device(dict(driver = soapy_device)) channels = list(range(device.getNumChannels(SoapySDR.SOAPY_SDR_RX))) print("Channels:", channels) ch = channels[0] sample_rates = device.listSampleRates(SoapySDR.SOAPY_SDR_RX, ch) print("Sample rates:\n", sample_rates) bandwidths = list(map(lambda r: int(r.maximum()), device.getBandwidthRange(SoapySDR.SOAPY_SDR_RX, ch))) print("Bandwidths:\n", bandwidths) print("Gain controls:") for gain in device.listGains(SoapySDR.SOAPY_SDR_RX, ch): print(" %s: %s" % (gain, device.getGainRange(SoapySDR.SOAPY_SDR_RX, ch, gain))) frequencies = device.listFrequencies(SoapySDR.SOAPY_SDR_RX, ch) print("Frequencies names:", frequencies) frequency_name = frequencies[0] print("Frequency channel name:", frequency_name) print("Frequency range:", device.getFrequencyRange(SoapySDR.SOAPY_SDR_RX, ch, frequency_name)[0])
Wir starten das Programm und sehen Informationen über den Empfänger:

Wir sehen, dass der Empfänger einen Eingangskanal mit dem Namen "RF", den möglichen Abtastfrequenzen [250000.0, 1024000.0, 1536000.0, 1792000.0, 1920000.0, 2048000.0, 2160000.0, 2560000.0, 2880000.0, 3200000.0] und dem Frequenzbereich 24 MHz-1.7 GHz hat.
Life Hack - Die gleichen Daten können auch über die Befehlszeile abgerufen werden, indem Sie den Befehl
SoapySDRUtil --probe = "driver = rtlsdr" eingeben .
Wenn wir das wissen, können wir den Datenstrom in WAV aufzeichnen. Wie im vorherigen Teil erwähnt, werden Daten vom SDR durch einen Strom von Signalen dargestellt, die als I und Q bezeichnet werden und Abtastwerte vom ADC sind. Sie können ungefähr als RAW-Daten von der Kamera dargestellt werden. Wer sich für weitere Details interessiert, kann
hier zum Beispiel lesen. Es reicht uns zu wissen, dass wir diese Daten schreiben können und andere SDR-Programme dann mit ihnen arbeiten können.
Der Datensatz selbst ist recht einfach: Die Funktion readStream füllt den Puffer, wenn Daten vorhanden sind. Wenn keine Daten vorhanden sind, wird -1 zurückgegeben. Unten finden Sie einen Datensatzcode mit 10 Beispielen (nicht wesentliche Teile des Codes werden weggelassen).
device.setFrequency(SoapySDR.SOAPY_SDR_RX, channel, "RF", frequency) device.setGain(SoapySDR.SOAPY_SDR_RX, channel, "TUNER", gain) device.setGainMode(SoapySDR.SOAPY_SDR_RX, channel, False) device.setSampleRate(SoapySDR.SOAPY_SDR_RX, channel, sample_rate)
Das Ergebnis im Screenshot:

Wie Sie sehen können, erhalten wir Datenblöcke vom Gerät. Die Größe eines Blocks beträgt 131072 Byte, was bei einer Abtastrate von 250.000 eine Dauer von etwa einer halben Sekunde ergibt. Im Allgemeinen haben diejenigen, die zuvor mit Soundkarten in Windows gearbeitet haben, viele Gemeinsamkeiten.
Schreiben Sie für den Test die Datei und überprüfen Sie, ob alles in Ordnung ist - sie kann in SDR # abgespielt werden. Es gibt noch einen Trick: Damit SDR # die Frequenzen der Sender korrekt anzeigt, muss der Dateiname in einem mit HDSDR kompatiblen Format in der Form „HDSDR_20190518_115500Z_101000kHz_RF.wav“ geschrieben werden (wie Sie sich vorstellen können, sind Datum und Uhrzeit zu Beginn in GMT angegeben, dann die Frequenz in Kilohertz) . Dies ist einfach in Python zu schreiben:
frequency = 101000000 file_name = "HDSDR_%s_%dkHz_RF.wav" % (datetime.datetime.utcnow().strftime("%Y%m%d_%H%M%SZ"), frequency/1000)
Überprüfen Sie zuerst das FM-Band. Alles ist in Ordnung, der Sender ist sichtbar, Musik spielt, RDS funktioniert.

Sie können mit der Aufnahme von NOAA beginnen.
NOAA-Aufnahme
Wir haben also einen Empfänger und ein Aufnahmeprogramm. Wir werden an den Wettersatelliten NOAA 15, NOAA 18 und NOAA 19 interessiert sein, die Bilder der Erdoberfläche mit Frequenzen von 137,620, 137,9125 und 137,100 MHz übertragen. Die Hauptschwierigkeit hierbei ist, dass Sie den Moment "einfangen" müssen, in dem der Satellit über uns fliegt. Die Flugzeit finden Sie online unter
https://www.n2yo.com/passes/?s=25338 ,
https://www.n2yo.com/passes/?s=28654 und
https://www.n2yo.com / passt /? s = 33591 .

Um nicht am Computer zu sitzen, fügen Sie dem Programm das Warten auf die richtige Zeit hinzu. Auf diese Weise können Sie das Programm auch auf dem Raspberry Pi ohne Display und Tastatur ausführen.
import datetime def wait_for_start(dt):
Übrigens müssen Sie den Befehl "nohup python recorder.py &" eingeben, um das Skript auf dem Raspberry Pi auszuführen und nach dem Schließen der Konsole funktionsfähig zu lassen.
Alles ist fertig, führen Sie das Skript aus und können andere Dinge tun, die Aufnahme dauert ca. 20 Minuten. Parallel dazu kann sich die Frage stellen: Ist es möglich, den Durchgang des Satelliten mit bloßem Auge zu sehen? Laut Tabelle beträgt seine maximale Helligkeit etwa 5,5 m, die Grenze des menschlichen Auges unter idealen Bedingungen beträgt 6 m. Das heißt, In einem wirklich dunklen Himmel, weit jenseits der Stadt, kann der Durchgang des NOAA-Satelliten theoretisch bemerkt werden. In der Stadt gibt es natürlich keine Chance (wie
sie über Habré geschrieben haben , ist eine Generation von Menschen, die die
Milchstraße noch nie in ihrem Leben gesehen haben, bereits gewachsen).
Das Ergebnis des Skripts ist eine aufgezeichnete WAV-Datei, deren Spektrum im Screenshot dargestellt ist.

Wir sehen ein vollständig unterscheidbares Signal, obwohl die Qualität mit einer
speziellen Antenne zum Empfangen von NOAA natürlich viel besser wäre. Das Signalformat heißt APT (
Automatic Picture Transmission ). Daraus können Sie ein Bild der Erdoberfläche erhalten. Wenn jemand interessiert ist, können Sie dessen Dekodierung separat betrachten. Aber es gibt natürlich vorgefertigte Programme, die Sie mit WxToImg oder MultiPSK dekodieren können.
Es ist interessant, die Doppler-Verschiebung im Spektrum zu sehen, die auftritt, weil der Satellit an uns vorbei fliegt. Wahrscheinlich ist es nicht schwierig, seine Geschwindigkeit zu berechnen, wenn man die Zeit- und Frequenzverschiebung in Hertz kennt.
Natürlich kann das Programm nicht nur zur Aufzeichnung von NOAA verwendet werden, in den Einstellungen können auch jede Bandbreite und Frequenz angegeben werden. Für diejenigen, die selbst mit SoapySDR experimentieren möchten, befindet sich der Programmcode vollständig unter dem Spoiler.
Quellcode from __future__ import print_function import SoapySDR import numpy as np import struct import sys import time import datetime def wait_for_start(dt):
SoapySDR plus ist, dass dasselbe Programm mit minimalen Änderungen mit anderen Empfängern funktioniert, beispielsweise mit SDRPlay oder HackRF. Auch plattformübergreifend wurde bereits erwähnt.
Wenn Leser immer noch Interesse am Thema Funkempfang haben, können Sie ein Beispiel für die Verwendung von SDR mit GNU Radio in Betracht ziehen, indem Sie mehrere virtuelle Empfänger auf der Basis einer Hardware erstellen.