Gqrx est un logiciel libre de type SDR (Software Defined Radio) qui permet de recevoir et de décoder des signaux radio. Développé sous Linux, il est également disponible pour macOS et Raspberry Pi. Gqrx utilise la bibliothèque GNU Radio et prend en charge de nombreux récepteurs SDR, tels que les dongles RTL-SDR, HackRF, et Funcube Dongle. Son interface graphique simple et conviviale permet de régler la fréquence, la bande passante, et d’afficher le spectre du signal en temps réel. Gqrx est largement utilisé pour des applications de surveillance des fréquences, de démodulation, et d’analyse de signaux radio.
Un script Python qui permet d’utiliser un joystick pour contrôler GQRX via son interface de contrôle à distance.
Ce script permet de :
Contrôler GQRX avec un joystick :
- Axe X : Ajuste la fréquence (gauche/droite)
- Axe Y : Contrôle le volume (haut/bas)
- Boutons : Préréglages de fréquences
Gamepad utilisé
Caractéristiques :
- Connexion automatique à GQRX via Telnet
- Détection automatique du joystick
- Contrôle précis avec zone morte
- Préréglages configurables
Le script
!/usr/bin/env python3
import pygame
import telnetlib
import time
import threading
import math
class GQRXJoystickControl:
def __init__(self, host="127.0.0.1", port=7356):
# Initialisation de pygame pour le joystick
pygame.init()
pygame.joystick.init()
# Configuration par défaut
self.host = host
self.port = port
self.connected = False
self.running = True
self.frequency = 100000000 # Fréquence de départ (100 MHz)
self.freq_step = 100 # Pas de fréquence par défaut
self.volume = 0 # Volume initial
# Essayer de se connecter à GQRX
self.connect_to_gqrx()
# Initialiser le joystick s'il est disponible
self.init_joystick()
# Thread pour la mise à jour continue
self.update_thread = threading.Thread(target=self.update_loop)
self.update_thread.daemon = True
self.update_thread.start()
def connect_to_gqrx(self):
"""Établir la connexion avec GQRX"""
try:
self.tn = telnetlib.Telnet(self.host, self.port)
self.connected = True
print("Connecté à GQRX")
# Configuration initiale
self.send_command("f") # Obtenir la fréquence actuelle
self.send_command("l NONE") # Désactiver le verrouillage
except Exception as e:
print(f"Erreur de connexion à GQRX: {e}")
self.connected = False
def init_joystick(self):
"""Initialiser le premier joystick trouvé"""
try:
if pygame.joystick.get_count() > 0:
self.joystick = pygame.joystick.Joystick(0)
self.joystick.init()
print(f"Joystick initialisé: {self.joystick.get_name()}")
else:
print("Aucun joystick trouvé")
self.joystick = None
except Exception as e:
print(f"Erreur d'initialisation du joystick: {e}")
self.joystick = None
def send_command(self, cmd):
"""Envoyer une commande à GQRX"""
if self.connected:
try:
self.tn.write(f"{cmd}\n".encode('ascii'))
response = self.tn.read_until(b"\n").decode('ascii').strip()
return response
except:
self.connected = False
print("Connexion perdue avec GQRX")
return None
def adjust_frequency(self, delta):
"""Ajuster la fréquence"""
self.frequency += delta
if self.connected:
self.send_command(f"F {self.frequency}")
print(f"Fréquence: {self.frequency/1000000:.3f} MHz")
def adjust_volume(self, value):
"""Ajuster le volume"""
self.volume = max(0, min(100, value))
if self.connected:
self.send_command(f"L SQL {self.volume}")
print(f"Volume: {self.volume}")
def process_joystick_input(self):
"""Traiter les entrées du joystick"""
if not self.joystick:
return
# Mise à jour des événements pygame
pygame.event.pump()
# Axe X pour la fréquence (axe 0)
freq_change = self.joystick.get_axis(0)
if abs(freq_change) > 0.1: # Zone morte
# Ajustement exponentiel pour un contrôle plus précis
direction = 1 if freq_change > 0 else -1
magnitude = math.pow(abs(freq_change), 2) * 10000
self.adjust_frequency(int(direction * magnitude))
# Axe Y pour le volume (axe 1)
volume_change = -self.joystick.get_axis(1) # Inversé pour que haut = plus fort
if abs(volume_change) > 0.1: # Zone morte
new_volume = int(self.volume + volume_change * 2)
self.adjust_volume(new_volume)
# Boutons pour les préréglages
for i in range(self.joystick.get_numbuttons()):
if self.joystick.get_button(i):
# Exemple de préréglages de fréquences
presets = {
0: 87500000, # FM Radio
1: 144800000, # 2m Amateur
2: 433500000, # 70cm Amateur
3: 156800000, # Marine VHF
}
if i in presets:
self.frequency = presets[i]
self.send_command(f"F {self.frequency}")
print(f"Préréglage {i+1}: {self.frequency/1000000:.3f} MHz")
def update_loop(self):
"""Boucle principale de mise à jour"""
while self.running:
if self.connected and self.joystick:
self.process_joystick_input()
time.sleep(0.05) # 20 Hz update rate
def cleanup(self):
"""Nettoyer les ressources"""
self.running = False
if self.connected:
self.tn.close()
pygame.quit()
if __name__ == "__main__":
try:
controller = GQRXJoystickControl()
print("Appuyez sur Ctrl+C pour quitter")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nArrêt du programme...")
controller.cleanup()
Prérequis :
Avoir Python installé et la bibliothèque pygame
Démarrer GQRX avec le contrôle distant activé
Lancer le script
Connecter votre joystick
SI python n’est pas installé :
Guide d’installation des prérequis pour le script GQRX-Joystick sous Ubuntu
Installation de Python
Pour Linux (Debian/Ubuntu) :
sudo apt update
sudo apt install python3 python3-pip
sudo apt-get install python3-pygame
Vérification de l’installation (facultatif)
import pygame
import sys
pygame.init()
pygame.joystick.init()
print(f"Python version: {sys.version}")
print(f"Pygame version: {pygame.version.ver}")
print(f"Nombre de joysticks détectés: {pygame.joystick.get_count()}")
if pygame.joystick.get_count() > 0:
joy = pygame.joystick.Joystick(0)
joy.init()
print(f"Joystick détecté: {joy.get_name()}")
Sur Linux, vous pourriez avoir besoin de permissions pour accéder au joystick :
sudo chmod a+rw /dev/input/js0
Rendre le fichier executable
sudo chmod +x gqrxjoystick.py
Résultat
./gqrxjoystick.py
Le projet reste ouvert aux contributions et peut évoluer selon les besoins des utilisateurs de GQRX.
A venir
Ajout d’une interface graphique (fonctionnelle mais en cours de développement)
Sur certains systèmes, vous devrez peut-être utiliser python3
et pip3
au lieu de python
et pip