RTL-SDR en Pythonï
Le RTL-SDR est de loin le SDR le plus abordable, Ă environ 40 âŹ, et un excellent choix pour dĂ©buter. Bien quâil ne permette que la rĂ©ception et que sa bande passante soit limitĂ©e Ă environ 1,75 GHz, il offre de nombreuses applications. Dans ce chapitre, nous apprendrons Ă configurer le logiciel RTL-SDR et Ă utiliser son API Python.
Contexte du RTL-SDRï
Le RTL-SDR a vu le jour vers 2010, lorsque certains ont dĂ©couvert quâil Ă©tait possible de pirater des dongles DVB-T bon marchĂ© Ă©quipĂ©s de la puce Realtek RTL2832U. Le DVB-T est une norme de tĂ©lĂ©vision numĂ©rique principalement utilisĂ©e en Europe. LâintĂ©rĂȘt du RTL2832U rĂ©sidait dans lâaccĂšs direct aux Ă©chantillons IQ bruts, permettant ainsi de concevoir un SDR (rĂ©cepteur audio numĂ©rique) polyvalent.
La puce RTL2832U intĂšgre le convertisseur analogique-numĂ©rique (CAN) et le contrĂŽleur USB, mais elle doit ĂȘtre associĂ©e Ă un tuner RF. Parmi les tuners les plus courants, on trouve les Rafael Micro R820T et R828D, ainsi que lâElonics E4000. La plage de frĂ©quences rĂ©glables dĂ©pend du tuner et se situe gĂ©nĂ©ralement entre 50 et 1700 MHz. La frĂ©quence dâĂ©chantillonnage maximale, quant Ă elle, est dĂ©terminĂ©e par le RTL2832U et le bus USB de votre ordinateur. Elle est gĂ©nĂ©ralement dâenviron 2,4 MHz, sans perte significative dâĂ©chantillons. Notez que ces tuners sont extrĂȘmement bon marchĂ© et prĂ©sentent une trĂšs faible sensibilitĂ© RF. Lâajout dâun amplificateur Ă faible bruit (LNA) et dâun filtre passe-bande est donc souvent nĂ©cessaire pour recevoir des signaux faibles.
Le RTL2832U utilise toujours des Ă©chantillons 8 bits ; lâordinateur hĂŽte recevra donc deux octets par Ă©chantillon IQ. Les RTL-SDR haut de gamme sont gĂ©nĂ©ralement Ă©quipĂ©s dâun oscillateur Ă tempĂ©rature contrĂŽlĂ©e (TCXO) en remplacement de lâoscillateur Ă quartz, moins coĂ»teux, ce qui assure une meilleure stabilitĂ© de frĂ©quence. Une autre option est le circuit de polarisation (bias-T), un circuit intĂ©grĂ© fournissant environ 4,5 V CC sur le connecteur SMA. Ce circuit permet dâalimenter facilement un LNA externe ou dâautres composants RF. Ce dĂ©calage CC supplĂ©mentaire se situe cĂŽtĂ© RF du SDR et nâinterfĂšre donc pas avec le fonctionnement de rĂ©ception.
Pour ceux qui sâintĂ©ressent Ă la direction dâarrivĂ©e (DOA) ou Ă dâautres applications de formation de faisceaux, le KrakenSDR est un SDR Ă cohĂ©rence de phase composĂ© de cinq RTL-SDR partageant un oscillateur et une horloge dâĂ©chantillonnage.
Installation du logicielï
Ubuntu (ou Ubuntu sous WSL)ï
Sur Ubuntu 20, 22 et autres systÚmes basés sur Debian, vous pouvez installer le logiciel RTL-SDR avec la commande suivante.
sudo apt install rtl-sdr
Cela va installer la bibliothĂšque librtlsdr , et les outils en lignes de commande suivants rtl_sdr, rtl_tcp, rtl_fm, and rtl_test.
Ensuite, installez le wrapper Python pour librtlsdr en utilisant :
sudo pip install pyrtlsdr
Si vous utilisez Ubuntu via WSL, tĂ©lĂ©chargez sous Windows la derniĂšre version de Zadig et exĂ©cutez-la pour installer le pilote « WinUSB » pour le RTL-SDR (il peut y avoir deux interfaces Bulk-In ; dans ce cas, installez « WinUSB » sur les deux). DĂ©branchez puis rebranchez le RTL-SDR une fois lâinstallation de Zadig terminĂ©e.
Ensuite, vous devrez configurer WSL pour quâil prenne en charge le pĂ©riphĂ©rique USB du RTL-SDR. Pour cela, installez dâabord la derniĂšre version de lâutilitaire usbipd (fichier MSI) (ce guide suppose que vous disposez de usbipd-win 4.0.0 ou version ultĂ©rieure), puis ouvrez PowerShell en mode administrateur et exĂ©cutez la commande suivante :
# (unplug RTL-SDR)
usbipd list
# (plug in RTL-SDR)
usbipd list
# (find the new device and substitute its index in the command below)
usbipd bind --busid 1-5
usbipd attach --wsl --busid 1-5
Du cÎté WSL, vous devriez pouvoir exécuter la commande lsusb et voir un nouvel élément nommé RTL2838 DVB-T ou un nom similaire.
Si vous rencontrez des problĂšmes dâautorisation (par exemple, le test ci-dessous ne fonctionne quâavec sudo), vous devrez configurer des rĂšgles udev. Commencez par exĂ©cuter lsusb pour trouver lâID du RTL-SDR, puis crĂ©ez le fichier /etc/udev/rules.d/10-rtl-sdr.rules avec le contenu suivant, en remplaçant idVendor et idProduct par ceux de votre RTL-SDR si nĂ©cessaire :
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", MODE="0666"
Pour actualiser udev, exécutez :
sudo udevadm control --reload-rules
sudo udevadm trigger
Si vous utilisez WSL et que le message dâerreur suivant sâaffiche Failed to send reload request: No such file or directory, cela signifie que le service udev nâest pas en cours dâexĂ©cution et que vous devrez exĂ©cuter la commande sudo nano /etc/wsl.conf et ajouter les lignes suivantes :
[boot]
command="service udev start"
RedĂ©marrez ensuite WSL Ă lâaide de la commande suivante dans PowerShell en tant quâadministrateur : wsl.exe --shutdown.
Il peut Ă©galement ĂȘtre nĂ©cessaire de dĂ©brancher puis de rebrancher le RTL-SDR (pour WSL, vous devrez relancer la commande usbipd attach).
Windowsï
For Windows users, see https://www.rtl-sdr.com/rtl-sdr-quick-start-guide/.
Test du RTL-SDRï
Si lâinstallation du logiciel a fonctionnĂ©, vous devriez pouvoir exĂ©cuter le test suivant, qui rĂ©glera le RTL-SDR sur la bande radio FM et enregistrera 1 million dâĂ©chantillons dans un fichier nommĂ© recording.iq dans /tmp.
rtl_sdr /tmp/recording.iq -s 2e6 -f 100e6 -n 1e6
Si vous obtenez le message No supported devices found, mĂȘme aprĂšs avoir ajoutĂ© sudo au dĂ©but de la commande, Linux ne dĂ©tecte pas le RTL-SDR. Si la dĂ©tection fonctionne avec sudo, il sâagit dâun problĂšme de configuration udev. Essayez de redĂ©marrer lâordinateur aprĂšs avoir suivi les instructions de configuration udev ci-dessus. Vous pouvez Ă©galement utiliser sudo pour toutes les opĂ©rations, y compris lâexĂ©cution de Python.
Vous pouvez tester la capacitĂ© de Python Ă dĂ©tecter le RTL-SDR Ă lâaide du script suivant :
from rtlsdr import RtlSdr
sdr = RtlSdr()
sdr.sample_rate = 2.048e6 # Hz
sdr.center_freq = 100e6 # Hz
sdr.freq_correction = 60 # PPM
sdr.gain = 'auto'
print(len(sdr.read_samples(1024)))
sdr.close()
qui devrait afficher :
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
1024
Code Python RTL-SDRï
Le code ci-dessus constitue un exemple dâutilisation basique du RTL-SDR en Python. Les sections suivantes dĂ©taillent les diffĂ©rents paramĂštres et astuces dâutilisation.
PrĂ©venir les dysfonctionnements du RTL-SDRï
Ă la fin de notre script, ou une fois lâacquisition des Ă©chantillons terminĂ©e, nous appellerons sdr.close(). Cela permettra dâĂ©viter que le RTL-SDR ne se bloque et nĂ©cessite dâĂȘtre dĂ©branchĂ©/rebranchĂ©. MalgrĂ© lâutilisation de close(), un blocage peut survenir ; vous le constaterez si le RTL-SDR se bloque pendant lâappel Ă read_samples(). Dans ce cas, vous devrez dĂ©brancher et rebrancher le RTL-SDR, et Ă©ventuellement redĂ©marrer votre ordinateur. Si vous utilisez WSL, vous devrez reconnecter le RTL-SDR Ă lâaide de usbipd.
RĂ©glage du gainï
En dĂ©finissant sdr.gain = 'auto', vous activez le contrĂŽle automatique du gain (CAG). Le RTL-SDR ajustera alors le gain de rĂ©ception en fonction des signaux reçus, afin dâoptimiser la capacitĂ© du convertisseur analogique-numĂ©rique (CAN) 8 bits sans le saturer. Dans de nombreuses situations, comme la rĂ©alisation dâun analyseur de spectre, il est utile de maintenir le gain Ă une valeur constante, ce qui implique un rĂ©glage manuel. Le gain du RTL-SDR nâest pas rĂ©glable en continu ; vous pouvez consulter la liste des valeurs de gain valides avec print(sdr.valid_gains_db). Si vous dĂ©finissez un gain qui ne figure pas dans cette liste, le systĂšme choisira automatiquement la valeur autorisĂ©e la plus proche. Vous pouvez vĂ©rifier le gain actuel avec print(sdr.gain). Dans lâexemple ci-dessous, le gain est rĂ©glĂ© Ă 49,6 dB et 4 096 Ă©chantillons sont reçus, puis reprĂ©sentĂ©s dans le domaine temporel :
from rtlsdr import RtlSdr
import numpy as np
import matplotlib.pyplot as plt
sdr = RtlSdr()
sdr.sample_rate = 2.048e6 # Hz
sdr.center_freq = 100e6 # Hz
sdr.freq_correction = 60 # PPM
print(sdr.valid_gains_db)
sdr.gain = 49.6
print(sdr.gain)
x = sdr.read_samples(4096)
sdr.close()
plt.plot(x.real)
plt.plot(x.imag)
plt.legend(["I", "Q"])
plt.savefig("../_images/rtlsdr-gain.svg", bbox_inches='tight')
plt.show()
Il y a quelques points Ă noter. Les 2 000 premiers Ă©chantillons environ semblent avoir une faible puissance de signal, car ils reprĂ©sentent des transitoires. Il est recommandĂ© de les ignorer Ă chaque exĂ©cution de script, par exemple en utilisant sdr.read_samples(2048) et en ne traitant pas la sortie. Par ailleurs, pyrtlsdr renvoie les Ă©chantillons sous forme de nombres Ă virgule flottante, compris entre -1 et +1. Bien quâil utilise un convertisseur analogique-numĂ©rique 8 bits et produise des valeurs entiĂšres, pyrtlsdr effectue une division par 127.0 pour simplifier les calculs.
FrĂ©quences dâĂ©chantillonnage autorisĂ©esï
La plupart des rĂ©cepteurs RTL-SDR nĂ©cessitent une frĂ©quence dâĂ©chantillonnage comprise entre 230 et 300 kHz, ou entre 900 et 3,2 MHz. Notez que les frĂ©quences Ă©levĂ©es, en particulier supĂ©rieures Ă 2,4 MHz, peuvent ne pas permettre dâobtenir 100 % des Ă©chantillons via la connexion USB. Si vous spĂ©cifiez une frĂ©quence dâĂ©chantillonnage non prise en charge, lâerreur suivante sâaffichera : rtlsdr.rtlsdr.LibUSBError: Error code -22: Could not set sample rate to 899000 Hz. Lors de la configuration dâune frĂ©quence dâĂ©chantillonnage autorisĂ©e, le message de la console affichera la frĂ©quence exacte ; cette valeur peut Ă©galement ĂȘtre obtenue en appelant la fonction sdr.sample_rate. Certaines applications peuvent tirer parti dâune valeur plus prĂ©cise pour leurs calculs.
Ă titre dâexercice, nous allons configurer la frĂ©quence dâĂ©chantillonnage Ă 2,4 MHz et crĂ©er un spectrogramme de la bande radio FM :
# ...
sdr.sample_rate = 2.4e6 # Hz
# ...
fft_size = 512
num_rows = 500
x = sdr.read_samples(2048) # get rid of initial empty samples
x = sdr.read_samples(fft_size*num_rows) # get all the samples we need for the spectrogram
spectrogram = np.zeros((num_rows, fft_size))
for i in range(num_rows):
spectrogram[i,:] = 10*np.log10(np.abs(np.fft.fftshift(np.fft.fft(x[i*fft_size:(i+1)*fft_size])))**2)
extent = [(sdr.center_freq + sdr.sample_rate/-2)/1e6,
(sdr.center_freq + sdr.sample_rate/2)/1e6,
len(x)/sdr.sample_rate, 0]
plt.imshow(spectrogram, aspect='auto', extent=extent)
plt.xlabel("Frequency [MHz]")
plt.ylabel("Time [s]")
plt.show()
RĂ©glage PPMï
Pour ceux qui sâintĂ©ressent au rĂ©glage PPM, sachez que chaque rĂ©cepteur RTL-SDR prĂ©sente un lĂ©ger dĂ©calage/erreur de frĂ©quence, dĂ» au faible coĂ»t des puces de tuner et Ă lâabsence dâĂ©talonnage. Ce dĂ©calage de frĂ©quence est relativement linĂ©aire (et non constant) sur lâensemble du spectre. On peut donc le corriger en saisissant une valeur PPM (parties par million). Par exemple, si vous syntonisez sur 100 MHz et que vous rĂ©glez le PPM sur 25, le signal reçu sera dĂ©calĂ© vers le haut de 100 x 10â¶ / (1 x 10â¶ * 25) = 2500 Hz. Lâimpact de lâerreur de frĂ©quence est plus important pour les signaux plus Ă©troits. Cela dit, de nombreux signaux modernes intĂšgrent une Ă©tape de synchronisation de frĂ©quence qui corrige tout dĂ©calage de frĂ©quence sur lâĂ©metteur, le rĂ©cepteur ou dĂ» Ă lâeffet Doppler.