PROJET SHACK — SELECTEUR D'ANTENNE & PILOTAGE DE ROTOR HY-GAIN HAM4

Un espace dédié aux échanges techniques entre radioamateurs : antennes, propagation, équipements, modes numériques, expérimentations et optimisations. Partagez vos connaissances et trouvez des solutions à vos questions !
Avatar de l’utilisateur
F4JLS
Filtre Passe-Bas
Messages : 23
Inscription : sam. mars 22, 2025 9:30 am
Localisation : Segré en Anjou Bleu
Contact :

PROJET SHACK — SELECTEUR D'ANTENNE & PILOTAGE DE ROTOR HY-GAIN HAM4

Message par F4JLS »

Bonjour à tous,

Je vous partage ici les débuts d’un projet à plus ou moins long terme.

Simple pour certains, compliqué pour d’autres, je vous propose d’avancer avec moi.

🔧 Étape 1 : point de départ

Nous commencerons par quelque chose de simple : remplacer le pupitre du sélecteur d’antenne Ameritron par un écran tactile afin d’afficher l’antenne sélectionnée.

En soi, ceci est surdimensionné techniquement, car en réalité le pupitre est simplement composé d’un sélecteur rotatif de diodes et d’une alimentation 12V.

Je commencerai donc ce projet sur cette base simple, avec une idée en tête : permettre une évolution progressive.

⚙️ Évolutions prévues

Comme beaucoup de mes projets, je souhaite qu’il puisse évoluer dans le temps :
  • Sécurisation de la sélection d’antenne via le signal CAT du poste
  • Blocage des changements d’antenne en cours d’émission
  • Utilisation des informations du poste pour une sélection automatique des antennes
🎯 Objectif final

À terme, l’objectif est d’intégrer également le contrôle du rotor dans ce même dispositif.

Ce système pourra ensuite être piloté par un logiciel de log, type LOG4OM2.

💬 À suivre…

Je partagerai les différentes étapes de l’avancement du projet.

N’hésitez pas à donner vos avis, idées ou retours d’expérience 👍
Ce n'est que de la radio! et pourtant ça pourrait bien vous changer la vie !
Avatar de l’utilisateur
F4JLS
Filtre Passe-Bas
Messages : 23
Inscription : sam. mars 22, 2025 9:30 am
Localisation : Segré en Anjou Bleu
Contact :

Re: PROJET SHACK — SELECTEUR D'ANTENNE & PILOTAGE DE ROTOR HY-GAIN HAM4

Message par F4JLS »

Bonjour,

Petit point de situation.

Dans un souci de simplicité, et afin de rajouter des étapes à la progression du système, je me suis contenté d’utiliser ce que j’avais sous la main, ou presque.

Je possédais un Arduino Uno ainsi qu’un écran alphanumérique.
J’avais bien commandé un écran LCD et des relais, mais cet écran avait un souci de compatibilité avec le logiciel de programmation (le problème classique des copies chinoises…).

Je me suis donc contenté d’utiliser un modèle Arduino plus petit, qui comporte également moins de ports GPIO.

Dans un premier temps, j’ai utilisé l’afficheur en mode 8 bits et j’ai connecté la carte relais.
Attention : celle-ci doit être alimentée en 12V même si elle est pilotée en 5V.

Une fois tout ce petit monde connecté, j’ai rajouté un puis deux boutons avec des résistances de pull-down.

Ces résistances imposent un état bas lorsque l’interrupteur est normalement ouvert.
Comme cela, le port d’entrée n’est pas flottant et n’est pas sensible aux parasites HF.

À chaque étape, j’utilise soit ChatGPT, soit Claude pour me générer de petits morceaux de programme de test.
Rien de compliqué, mais il est vrai que cela fonctionne très bien.

Après, il suffit simplement de jouer avec le texte et les variables.

Comme j’utilisais beaucoup de ports, j’ai décidé de passer l’afficheur en mode 4 bits.
(C’est théoriquement plus lent, car les informations sont envoyées deux fois moins rapidement.)

Au final, aucune différence visible avec le mode 8 bits, mais cela me libère plusieurs ports GPIO.

J’ai donc pris la décision de commander un boîtier ainsi qu’un convertisseur RS232 afin de récupérer les informations du poste via la sortie DB9 CAT.

Je vais également remplacer les deux boutons par un sélecteur rotatif avec poussoir intégré afin de valider le choix de l’antenne.

Un interrupteur permettra aussi de passer le système en mode sélection d’antenne AUTO ou manuel.

Voilà une petite photo du système ainsi qu’un exemple de code.
Image

// ============================================================
// SELECTEUR ANTENNE — F4JLS
// Arduino UNO + LCD 16x2 + 2 boutons + 5 relais
// Version amelioree
// ============================================================

#include <LiquidCrystal.h>

// LCD en mode 4 bits : RS, EN, D4, D5, D6, D7
LiquidCrystal lcd(6, 7, 2, 3, 4, 5);

// ── Relais ───────────────────────────────────────────────────
// IMPORTANT : verifier le sens de ta carte relais
// Si les relais s'activent a l'envers → changer RELAIS_ON/OFF
#define RELAIS_ON HIGH // changer en LOW si carte logique inversee
#define RELAIS_OFF LOW // changer en HIGH si carte logique inversee

const int relaisPins[] = {8, 9, 10, 11, 12};
const int NB_ANTENNES = 5;

// ── Noms antennes (16 caracteres max !) ──────────────────────
const char* antennes[] = {
"Antenne en panne ",
"Hexbeam 40m ",
"Hexbeam 20-6m : ",
"NON CONNECTE ",
"NON CONNECTE",
};

// ── Boutons ──────────────────────────────────────────────────
const int boutonSuivant = A0;
const int boutonValider = A1;

// ── Variables etat ───────────────────────────────────────────
int indexSelectionne = 2; // antenne affichee en cours de navigation
int indexActif = 2; // antenne reellement active sur les relais
bool dernierEtatSuiv = HIGH;
bool dernierEtatValid = HIGH;
unsigned long dernierDebounce = 0;
const long DEBOUNCE_DELAI = 200; // ms

// ============================================================
void setup() {
Serial.begin(9600);
Serial.println(F("F4JLS — Selecteur antenne demarre"));

lcd.begin(16, 2);

// Boutons avec pull-up interne
pinMode(boutonSuivant, INPUT_PULLUP);
pinMode(boutonValider, INPUT_PULLUP);

// Initialiser tous les relais OFF
for (int i = 0; i < NB_ANTENNES; i++) {
pinMode(relaisPins, OUTPUT);
digitalWrite(relaisPins, RELAIS_OFF);
}

// Activer antenne par defaut au demarrage (Hexbeam)
activerAntenne(indexActif);

afficherMenu();
}

// ============================================================
void loop() {
bool etatSuiv = digitalRead(boutonSuivant);
bool etatValid = digitalRead(boutonValider);

// ── Bouton SUIVANT ────────────────────────────────────────
if (etatSuiv == LOW && dernierEtatSuiv == HIGH) {
if (millis() - dernierDebounce > DEBOUNCE_DELAI) {
dernierDebounce = millis();

indexSelectionne++;
if (indexSelectionne >= NB_ANTENNES) indexSelectionne = 0;

afficherMenu();
Serial.print(F("Navigation -> "));
Serial.println(antennes[indexSelectionne]);
}
}

// ── Bouton VALIDER ────────────────────────────────────────
if (etatValid == LOW && dernierEtatValid == HIGH) {
if (millis() - dernierDebounce > DEBOUNCE_DELAI) {
dernierDebounce = millis();

if (indexSelectionne == indexActif) {
// Meme antenne deja active — juste un rappel
afficherDejaActive();
} else {
// Nouvelle antenne → commutation
activerAntenne(indexSelectionne);
afficherConfirmation();
}
}
}

dernierEtatSuiv = etatSuiv;
dernierEtatValid = etatValid;
}

// ============================================================
// Active un relais et coupe tous les autres
// ============================================================
void activerAntenne(int index) {
// Securite : couper tous les relais d'abord
for (int i = 0; i < NB_ANTENNES; i++) {
digitalWrite(relaisPins, RELAIS_OFF);
}
delay(50); // petite pause de securite

// Activer le bon relais
digitalWrite(relaisPins[index], RELAIS_ON);
indexActif = index;

Serial.print(F("Antenne active : "));
Serial.println(antennes[indexActif]);
}

// ============================================================
// Affiche le menu de navigation
// ============================================================
void afficherMenu() {
lcd.clear();

// Ligne 1 : antenne en cours de navigation avec fleche
lcd.setCursor(0, 0);
if (indexSelectionne == indexActif) {
lcd.print("*"); // etoile si c'est l'antenne active
} else {
lcd.print(">"); // fleche si c'est une autre antenne
}
lcd.print(antennes[indexSelectionne]);

// Ligne 2 : antenne actuellement active
lcd.setCursor(0, 1);
lcd.print("ACT:");
// Afficher les 12 premiers caracteres du nom actif
char nomCourt[13];
strncpy(nomCourt, antennes[indexActif], 12);
nomCourt[12] = '\0';
lcd.print(nomCourt);
}

// ============================================================
// Affiche confirmation apres commutation
// ============================================================
void afficherConfirmation() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("OK! Commute sur:");
lcd.setCursor(0, 1);
// Afficher les 16 premiers caracteres
char nomCourt[17];
strncpy(nomCourt, antennes[indexActif], 16);
nomCourt[16] = '\0';
lcd.print(nomCourt);

delay(2000);
afficherMenu();
}

// ============================================================
// Affiche message si antenne deja active
// ============================================================
void afficherDejaActive() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Deja active !");
lcd.setCursor(0, 1);
char nomCourt[17];
strncpy(nomCourt, antennes[indexActif], 16);
nomCourt[16] = '\0';
lcd.print(nomCourt);

delay(1500);
afficherMenu();
}
Ce n'est que de la radio! et pourtant ça pourrait bien vous changer la vie !
Répondre