Salut, Habr.
La
deuxième partie a examiné les aspects pratiques de l'utilisation du SDR. Dans cette partie, nous verrons comment recevoir des données de satellites météorologiques NOAA en utilisant Python et le récepteur RTL-SDR bon marché (30 $). Le code considéré fonctionnera partout - sur Windows, OSX, Linux et même sur le Raspberry Pi.

Peu importe, a continué sous la coupe.
SoapySDR
Il existe de nombreux fabricants de divers appareils SDR, et il serait très gênant de les prendre en charge séparément, et cela coûte cher en termes d’achat de matériel pour les tests. En principe, pour l'accès unifié, il existe deux bibliothèques qui sont devenues essentiellement la norme. La première est l'interface assez ancienne de la
DLL ExtIO , qui a probablement pas moins de 10 ans, la seconde est la bibliothèque
SoapySDR plus moderne, que nous examinerons.
SoapySDR est un ensemble de bibliothèques multiplateformes écrites en C ++ qui fournissent un accès unifié aux appareils SDR, récepteurs et émetteurs-récepteurs. Si le fabricant crée une telle interface, son appareil fonctionnera automatiquement avec un assez grand nombre de programmes populaires (GQRX, GNU Radio, CubicSDR, etc.). Presque tous les fabricants adéquats, à l'exception de certains,
(saisissant cette occasion, j'envoie mes salutations à EE) ont le support SoapySDR, une liste des appareils pris en charge peut être trouvée
sur la page du projet . Comme vous pouvez le voir, il est assez grand et comprend HackRF, USRP, SDRPlay, LimeSDR, RTL-SDR, Red Pitaya et bien d'autres.
La bibliothèque SoapySDR est multiplateforme, c'est-à-dire le code écrit pour cela fonctionnera sous Windows, OSX, Linux et même sur le Raspberry Pi. Pour Windows, les bibliothèques requises font partie du package
PothosSDR ; pour les autres plates-formes, SoapySDR devra être compilé indépendamment. Il est nécessaire de compiler deux parties - la
bibliothèque elle -
même et le «plug-in» pour le récepteur souhaité, dans notre cas, ce sera
SoapyRTLSDR (sous Windows, la bibliothèque peut également être assemblée à partir de la source, pour cela, vous avez besoin de Visual Studio, Cmake et SWIG). Maintenant, tout est prêt et vous pouvez écrire du code.
Nous importons la bibliothèque et obtenons une liste de récepteurs:
from __future__ import print_function import SoapySDR
Nous connectons le récepteur, exécutons le code et voyons une liste d'appareils, parmi lesquels se trouve notre rtlsdr.

Les autres appareils sont des cartes son, comme nous le rappelons, historiquement, les premiers SDR fonctionnaient précisément via l'entrée linéaire du PC, et la bibliothèque les prend également en charge. Nous obtenons des informations sur l'appareil - le nombre de canaux disponibles, la gamme de fréquences, etc.:
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])
Nous commençons le programme et voyons des informations sur le récepteur:

Nous voyons que le récepteur a un canal d'entrée avec le nom "RF", les fréquences d'échantillonnage possibles [250000.0, 1024000.0, 1536000.0, 1792000.0, 1920000.0, 2048000.0, 2160000.0, 2560000.0, 2880000.0, 3200000.0] et la plage de fréquences de 24 MHz-1,7 GHz.
Life hack - les mêmes données peuvent également être obtenues à partir de la ligne de commande en tapant la commande
SoapySDRUtil --probe = "driver = rtlsdr" .
Sachant cela, nous pouvons enregistrer le flux de données en WAV. Comme mentionné dans la partie précédente, les données du SDR sont représentées par un flux de signaux appelés I et Q, qui sont des échantillons de l'ADC, grossièrement ils peuvent être représentés comme des données RAW de la caméra. Toute personne intéressée par plus de détails peut lire, par exemple,
ici . Il nous suffit de savoir que nous pouvons écrire ces données, et d'autres programmes SDR peuvent ensuite travailler avec eux.
L'enregistrement lui-même est assez simple - la fonction readStream remplit le tampon s'il y a des données, s'il n'y a pas encore de données, alors -1 sera retourné. Vous trouverez ci-dessous un code d'enregistrement de 10 échantillons (les parties non essentielles du code sont omises).
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)
Le résultat dans la capture d'écran:

Comme vous pouvez le voir, nous recevons des blocs de données de l'appareil, la taille d'un bloc est de 131072 octets, ce qui à un taux d'échantillonnage de 250 000 nous donne une durée d'environ une demi-seconde. En général, ceux qui ont déjà travaillé avec des cartes son sous Windows trouveront beaucoup en commun.
Pour le test, écrivez le fichier et vérifiez que tout va bien - il peut être lu en SDR #. Il y a une autre astuce ici - pour que SDR # affiche correctement les fréquences des stations, le nom du fichier doit être écrit dans un format compatible avec HDSDR, de la forme "HDSDR_20190518_115500Z_101000kHz_RF.wav" (comme vous pouvez le deviner, la date et l'heure sont en GMT au début, puis la fréquence en kilohertz) . C'est facile à écrire en Python:
frequency = 101000000 file_name = "HDSDR_%s_%dkHz_RF.wav" % (datetime.datetime.utcnow().strftime("%Y%m%d_%H%M%SZ"), frequency/1000)
Tout d'abord, vérifiez la bande FM. Tout va bien, la station est visible, la musique joue, RDS fonctionne.

Vous pouvez commencer à enregistrer la NOAA.
Apport de NOAA
Nous avons donc un récepteur et un programme d'enregistrement. Nous serons intéressés par les satellites météorologiques NOAA 15, NOAA 18 et NOAA 19 transmettant des images de la surface de la Terre à des fréquences de 137,620, 137,9125 et 137,100 MHz. La principale difficulté ici est que vous devez "attraper" le moment où le satellite survole nous. Vous pouvez connaître le temps de vol en ligne sur
https://www.n2yo.com/passes/?s=25338 ,
https://www.n2yo.com/passes/?s=28654 et
https://www.n2yo.com / passe /? s = 33591 respectivement.

Afin de ne pas vous asseoir devant l'ordinateur, ajoutez au programme l'attente au bon moment. Cela vous permettra également d'exécuter le programme sur le Raspberry Pi, sans écran ni clavier.
import datetime def wait_for_start(dt):
Par ailleurs, pour exécuter le script sur le Raspberry Pi et le laisser fonctionner après avoir fermé la console, vous devez entrer la commande "nohup python recorder.py &".
Tout est prêt, lancez le script et pouvez faire autre chose, l'enregistrement dure environ 20 minutes. En parallèle, la question peut se poser - est-il possible de voir le passage du satellite à l'œil nu? Selon le tableau, sa luminosité maximale est d'environ 5,5 m, la limite de l'œil humain dans des conditions idéales est de 6 m. C'est-à-dire dans un ciel vraiment sombre, bien au-delà de la ville, le passage du satellite NOAA peut théoriquement être remarqué, dans la ville, bien sûr, il n'y a aucune chance (comme
ils l'ont écrit sur Habré , une génération de gens qui n'ont jamais vu la
Voie lactée dans leur vie a déjà grandi).
Le résultat du script est un fichier wav enregistré, son spectre est montré dans la capture d'écran.

Nous voyons un signal complètement distinct, bien que, bien sûr, avec une
antenne spéciale pour recevoir la NOAA, la qualité serait bien meilleure. Le format du signal est appelé APT (
Automatic Picture Transmission ), à partir duquel vous pouvez obtenir une image de la surface de la terre, si quelqu'un est intéressé, vous pouvez considérer séparément son décodage. Mais il existe bien sûr des programmes prêts à l'emploi, vous pouvez décoder de tels signaux en utilisant WxToImg ou MultiPSK.
Il est intéressant de voir le décalage Doppler dans le spectre, qui se produit parce que le satellite passe devant nous. Probablement, il n'est pas difficile de calculer sa vitesse, connaissant le décalage horaire et fréquentiel en hertz.
Bien sûr, le programme peut être utilisé non seulement pour l'enregistrement de NOAA, mais toute bande passante et fréquence peuvent être spécifiées dans les paramètres. Pour ceux qui veulent expérimenter eux-mêmes SoapySDR, le code du programme est entièrement situé sous le spoiler.
Code source 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 est que le même programme avec des changements minimes fonctionnera avec d'autres récepteurs, tels que SDRPlay ou HackRF. Eh bien, à propos de multiplateforme, a également été mentionné.
Si les lecteurs s'intéressent toujours au sujet de la réception radio, vous pouvez envisager un exemple d'utilisation de SDR avec GNU Radio en créant plusieurs récepteurs virtuels basés sur un matériel.