Arduino et la radio, à la poursuite des satellites.
Je suis depuis des années en admiration devant ces radioamateurs qui ont automatisé la rotation de leurs antennes afin de poursuivre les satellites.
J’ai lu de nombreuses publications et je suis toujours resté sur ma faim, car j’ai trouvé peu de montages simplement reproductibles que ce soit au niveau mécanique ou programmation.
(Les équipements du commerce existent mais …. pas de ça chez nous !)
Voilà donc une première description d’un montage et son logiciel à la portée de tous. Je me contente de corriger automatiquement l’Azimut (le plan horizontal) de la ou des antennes.
En effet pour débuter, on va utiliser des antennes assez « courtes » d’environ 1,5 mètre de longueur, elles ont un angle d’ouverture assez large d’environ 30° (à -3dB), si on place cette antenne avec une inclinaison de 30°, on recevra pratiquement sans perte les satellites évoluant entre l’horizon et 60°. C’est avec ce genre d’installation que j’ai réalisé jusqu’à maintenant de nombreux contacts ou reçu divers satellites.
Comment ça marche ?
On va utiliser un logiciel de poursuite (Orbitron pour mes essais, mais SDR-CONSOLE sait faire), on va « capturer » les informations sur le positionnement du satellite pour les envoyer sur un port de communication de notre ordinateur. A l’aide de l’interface Arduino on va lire les données et les comparer avec la position de notre moteur et faire les corrections nécessaires en faisant tourner notre moteur à « droite » ou à « gauche » .
L’interface Ordinateur -> Moteur
Elle est composée d’un Arduino pour effectuer les calculs, mesurer la position du moteur et commuter les relais pour faire tourner notre moteur à gauche ou à droite ou …. stop !
Le coût de cette interface est de 5,5€ ! (restera à la mettre dans un boitier).
Et le moteur ?
Je me suis contenté d’automatiser un vieux rotor d’antenne ce qui réduit considérablement l’aspect mécanique. Il y a d’ailleurs 2 options remplacer le boitier de contrôle du rotor par notre interface, ou à l’aide notre interface piloter le boitier rotor, c’est le même montage, dans le premier cas nos relais vont directement commander le moteur, dans le second ils vont se substituer aux boutons « Gauche » « Droite » du boitier de commande.
Fonctionnement de l’interface :
Arduino possède un port de communication, des entrées/sorties logiques et analogiques, on va donc utiliser une entrée analogique pour mesurer le potentiomètre du moteur, et convertir en degrés.
Sur le port de communication on va lire les données de site et azimut en provenance de l’ordinateur (on n’utilisera que l’azimut dans cette version), on va comparer la position du moteur et celle du satellite et si nécessaire on va activer le moteur à « gauche » ou à « droite », les relais seront connectés sur des sorties logiques.
Un afficheur parallèle (connecté sur des sorties logiques) nous permettra de suivre les informations satellite et moteur.
Câblage :
je suis désolé, mais tout est là, rien de plus !
bien sûr, après la maquette, j’ai câblé « en dur » avec des fils en nappe.
Et le programme ?
Pour les non initiés, voici rapidement comment on procède :
– Le programme en langage C est écrit sur un PC.
– Il est compilé et envoyé sur l’Arduino (et il y reste même si on éteint)
– Dés que l’Arduino est sous tension le programme s’exécute.
Vous n’êtes donc pas obligé de programmer, il suffit d’injecter le programme compilé par le port USB de l’Arduino.
Le satellite poursuivi est visible (E:004 = 4° d’élévation), il est a 59° d’azimut et l’antenne est a 57°, on ne bouge pas tant que l’écart n’est pas au moins de 4°.
Algorithme :
Le programme :
J’ai fait au plus simple ! Je surveille quand même le site (élévation) pour vérifier si le satellite est au dessus de l’horizon .
///////////////////////////////////////////////
// Pilotage rotor azimut à l'aide de WispDDE //
// Gilles PLATRET F1EFW //
///////////////////////////////////////////////
// On ajoute une librairie qui va nous aider pour l'affichage
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// On déclare quelques variables
String Lecture_Port_USB,A_AZI,A_ELE,A_Potar_Azi,A_Potar_Ele ;
int AZI, ELE, Potar_Azi;
int pin0 = 0;
// On initialise le programme
void setup() {
lcd.begin(16, 2);
Serial.begin(9600); // vitesse avec le port de communication
pinMode(5, OUTPUT); // relais 1
pinMode(6, OUTPUT); // relais 2
digitalWrite(5, HIGH); // relais au repos en effet ils sont inversés
digitalWrite(6, HIGH); // HIGH repos LOW travail
AZI=0,ELE=0;
}
// On commence à bosser
void loop()
{
// Lecture du port de communication.
// au format GS-232 -> ex W127 052
// on extrait les caractères 2a4 Azumuth et 5a8 Elevation (substring)
// et on les convertis en nombres (ToInt)
// On dispose de l'information sous format numérique pour les calculs
// et au format chaine de caractères pour l'affichage
while(Serial.available()){
Lecture_Port_USB = Serial.readString();
A_AZI = (Lecture_Port_USB.substring(1, 4));
A_ELE = (Lecture_Port_USB.substring(5, 8));
AZI = (A_AZI.toInt());
ELE = (A_ELE.toInt());
lcd.setCursor(0, 0);
lcd.print("SAT A:");
lcd.print(A_AZI);
lcd.print(" E:");
lcd.print(A_ELE);
}
// fin de lecture du port USB
// Lecture du potar_Azumuth
// Potar_Azi varie de 0 a 1024 (0 quand il est à la masse et 1024 quand il reçoit 5V)
// pour convertir en degres on fera 1024/360 = 2.84
Potar_Azi = (analogRead(pin0)/2.84);
lcd.setCursor(0, 1);
lcd.print("ANT A:");
// pour afficher le nombre sous la forme de 3 caractères
// c'est pas très élégant .... je ferais mieux plus tard
A_Potar_Azi = String(Potar_Azi);
if (A_Potar_Azi.length() < 2) {
A_Potar_Azi = ("00"+ A_Potar_Azi);
}
else {
if (A_Potar_Azi.length() < 3) {
A_Potar_Azi = ("0"+ A_Potar_Azi);
}
}
lcd.print(A_Potar_Azi);
// on ne corrige que tous les 4 degrés et si le satellite est visible (ELE>0)
// donc si différence des valeurs > 4 on tourne dans un sens
// si < 4 on tourne dans l'autre sens et si presque égale on stoppe
if ((Potar_Azi > AZI)&&(abs(Potar_Azi - AZI)>4)&&(ELE>0)) {
digitalWrite (5, HIGH);
digitalWrite (6, LOW);
}
if ((Potar_Azi < AZI)&&(abs(Potar_Azi - AZI)>4)&&(ELE>0)) {
digitalWrite (5, LOW);
digitalWrite (6, HIGH);
}
if ((abs(Potar_Azi - AZI)<5)||(ELE<1)) {
digitalWrite (5, HIGH);
digitalWrite (6, HIGH);
delay (200);
}
}
Et maintenant ?
– Activation de la fonctionnalité SITE en utilisant un vérin
– Montage sur un mat avec 1 antenne VHF et une UHF et on fait joujou.
Toujours à votre disposition, (formulaire de contact)
amicalement Gilles
Merci Gilles pour cette belle description.