La télécommande GTRC est maintenant assemblée et l’environnement Arduino nécessaire à sa programmation a été préparé dans l’article précédent.

Il reste à installer et configurer son programme.

À première vue, le nombre de fichiers constituant le logiciel peut sembler important. Cette organisation permet cependant de séparer les différentes fonctions de la télécommande et, surtout, de limiter les modifications nécessaires à sa configuration.

La plupart des fichiers n’ont donc pas vocation à être modifiés.

Cet article présente l’organisation du programme de la télécommande GTRC V1.0, les principaux paramètres pouvant être adaptés et la procédure permettant de compiler puis de téléverser le programme dans l’Arduino Uno.


Le programme complet de la télécommande GTRC V1.0 est disponible sur le dépôt du projet :

GTRC_Handset_V1_0

Après téléchargement et décompression de l’archive, tous les fichiers doivent être conservés dans le même dossier.

Le fichier principal possède l’extension .ino. Un double-clic sur celui-ci permet d’ouvrir le projet dans Arduino IDE.

Arduino IDE affiche alors les différents fichiers du programme sous forme d’onglets.


Comme expliqué dans l’article précédent, le logiciel GTRC est organisé en plusieurs modules.

Chaque partie possède une fonction précise.

FichierFonction principale
.inoInitialisation et coordination générale
Config.hConfiguration matérielle et paramètres généraux
Locomotives.cpp / .hListe des locomotives et positions du sélecteur
Inputs.cpp / .hLecture du sélecteur, du potentiomètre et des boutons
Display.cpp / .hGestion de l’écran OLED
Radio.cpp / .hCommunication radio NRF24L01
Types.hStructures de données et commandes du protocole
Logo.cpp / .hImages affichées sur l’écran
Version.hNuméro de version du logiciel

Cette séparation facilite la maintenance du programme.

Une modification de l’affichage reste par exemple principalement confinée dans Display.cpp, tandis qu’une évolution de la communication radio concerne essentiellement Radio.cpp.

Pour une utilisation normale de GTRC, il n’est pas nécessaire de comprendre en détail le contenu de tous ces fichiers.


Le fichier .ino constitue le point d’entrée du programme.

Comme dans la plupart des programmes Arduino, deux fonctions principales y sont présentes :

void setup()
{
    ...
}

void loop()
{
    ...
}

La fonction setup() est exécutée une seule fois lors de la mise sous tension de la télécommande.

Elle initialise notamment les différents états du programme, les entrées, l’écran et la communication radio.

La fonction loop() est ensuite exécutée continuellement.

Elle coordonne les différentes fonctions de la télécommande :

  • lecture des commandes ;
  • conduite de la locomotive sélectionnée ;
  • gestion de l’éclairage ;
  • arrêt d’urgence ;
  • mode MEM ;
  • mode diagnostic ;
  • communication radio ;
  • mise à jour de l’affichage.

Le fichier .ino joue donc essentiellement le rôle de chef d’orchestre entre les différents modules.

Il n’a normalement pas besoin d’être modifié pour adapter GTRC à un réseau particulier.


Les fichiers Inputs.cpp et Inputs.h assurent la lecture des différentes commandes physiques de la télécommande :

  • sélecteur de locomotive ;
  • potentiomètre de conduite ;
  • bouton d’arrêt d’urgence ;
  • bouton LIGHT.

Le sélecteur 12 positions fonctionne grâce au pont de résistances présenté lors de la fabrication de la télécommande.

Chaque position produit une tension différente sur l’entrée analogique A0. Le programme mesure cette tension et détermine la locomotive correspondante.

Le module gère également les deux utilisations du bouton LIGHT :

  • appui court : commande de l’éclairage ;
  • appui long : commande liée au mode MEM.

La durée séparant les deux types d’appui est configurable dans Config.h.

Ce module ne nécessite normalement aucune modification.


Les fichiers Display.cpp et Display.h regroupent les fonctions nécessaires à l’affichage sur l’écran OLED 128 × 64.

L’affichage permet notamment de présenter :

  • le nom de la locomotive ;
  • son identifiant ;
  • la position du potentiomètre ;
  • la direction ;
  • la barre de vitesse ;
  • l’état de l’éclairage ;
  • l’état de l’arrêt d’urgence ;
  • le mode MEM ;
  • la tension de la batterie de la télécommande ;
  • les informations du mode diagnostic.

La bibliothèque U8g2 assure le pilotage de l’écran.

GTRC utilise son mode PAGE, particulièrement intéressant sur un Arduino Uno car il permet de limiter la quantité de mémoire SRAM utilisée pour l’affichage.

La configuration du contrôleur OLED mérite cependant une attention particulière.


Le choix s’effectue directement dans Config.h, voir plus loin dans l’article.

Display.cpp sélectionne ensuite automatiquement le constructeur correspondant de la bibliothèque U8g2.

Le reste du programme d’affichage reste identique.

Ce principe permet de conserver les choix matériels dans Config.h sans avoir à intervenir dans le fonctionnement interne du module d’affichage.


Les fichiers Radio.cpp et Radio.h assurent la communication avec les récepteurs installés dans les locomotives.

La télécommande utilise pour cela un module NRF24L01 et la bibliothèque NRFLite.

Ce module prend notamment en charge :

  • les commandes normales de conduite ;
  • l’arrêt d’urgence ;
  • la libération de l’arrêt d’urgence ;
  • les commandes du mode MEM ;
  • les requêtes du mode diagnostic ;
  • la réception des réponses de diagnostic.

La télécommande et les récepteurs doivent évidemment utiliser le même protocole.

Il est donc déconseillé de modifier directement Radio.cpp pour personnaliser une installation. Les paramètres prévus à cet effet sont regroupés dans les fichiers de configuration.


Le fichier Types.h contient les structures de données et les différents types de commandes utilisés par le programme.

Il définit notamment les informations constituant les paquets échangés entre la télécommande et les locomotives.

Il représente en quelque sorte le langage commun du réseau GTRC.

Télécommande et récepteurs doivent interpréter ces informations de la même manière.

Ce fichier ne doit donc pas être modifié pour une configuration normale du système.


Les fichiers Logo.cpp et Logo.h contiennent les éléments graphiques utilisés lors du démarrage de la télécommande.

Version.h centralise quant à lui le numéro de version du programme.

La première version publique du projet porte désormais le nom :

GTRC V1.0

Cette nouvelle numérotation remplace la numérotation utilisée pendant les différentes phases de développement du projet.


Malgré le nombre de fichiers constituant le programme, la configuration courante de la télécommande concerne principalement :

  • Config.h ;
  • Locomotives.cpp.

Config.h regroupe les paramètres matériels et certains réglages généraux.

Locomotives.cpp contient la correspondance entre les positions du sélecteur et les locomotives ainsi que leurs noms.

Ces deux fichiers sont donc les plus importants à connaître pour adapter la télécommande.


Config.h centralise une grande partie des paramètres susceptibles de dépendre du matériel utilisé.

Type d’écran OLED

Deux écrans OLED 128 × 64 extérieurement presque identiques peuvent utiliser des contrôleurs différents.

Les modèles couramment rencontrés utilisent notamment :

  • SH1106 ;
  • SSD1306.

La résolution 128 × 64 ne suffit donc pas à identifier le contrôleur de l’écran.

La télécommande ayant servi au développement de GTRC est équipée d’un SH1106, mais la version GTRC V1.0 permet également de sélectionner un écran SSD1306 sans modifier Display.cpp.

Le choix entre SH1106 et SSD1306 est effectué ici :

#define OLED_TYPE_SH1106   1
#define OLED_TYPE_SSD1306  2

#define OLED_TYPE OLED_TYPE_SH1106

Avec le matériel présenté dans les articles précédents, la dernière ligne reste configurée sur :

#define OLED_TYPE OLED_TYPE_SH1106

Les dimensions de l’écran sont également définies :

#define OLED_WIDTH  128
#define OLED_HEIGHT 64

Entrées analogiques

Les trois entrées analogiques utilisées par la télécommande sont :

const uint8_t PIN_SELECTOR = A0;
const uint8_t PIN_THROTTLE = A1;
const uint8_t PIN_BATTERY  = A2;

Elles correspondent respectivement :

  • au sélecteur 12 positions ;
  • au potentiomètre de conduite ;
  • à la mesure de tension de la batterie.

Ces valeurs correspondent au câblage présenté lors de la fabrication de la télécommande et n’ont normalement pas besoin d’être modifiées.


Boutons

Les deux boutons actuellement utilisés sont définis ainsi :

const uint8_t PIN_ESTOP = 2;
const uint8_t PIN_LIGHT = 3;

Le bouton d’arrêt d’urgence est donc connecté sur D2 et le bouton LIGHT sur D3.

Deux entrées supplémentaires ont été prévues dans l’architecture pour de futures fonctions.


Identifiant de la télécommande

La télécommande possède son propre identifiant radio :

const uint8_t RADIO_ID = 1;

Cet identifiant correspond à l’adresse physique utilisée par le NRF24L01 de la télécommande.

Il ne doit pas être confondu avec les identifiants des locomotives.


Adresse du réseau GTRC

Les récepteurs des locomotives partagent une adresse radio physique commune :

const uint8_t GTRC_RADIO_NETWORK_ID = 200;

La télécommande transmet les commandes vers cette adresse.

L’identification de la locomotive concernée est ensuite effectuée grâce à l’identifiant logique contenu dans le paquet radio.

La valeur doit être cohérente avec celle configurée dans les récepteurs.


Broches du NRF24L01

Le module NRF24L01 de la télécommande utilise :

const uint8_t PIN_NRF_CE  = 9;
const uint8_t PIN_NRF_CSN = 10;

Les autres signaux passent par le bus SPI matériel de l’Arduino Uno, comme présenté dans l’article consacré au câblage.


Canal radio

Le canal utilisé par GTRC est défini par :

const uint8_t RADIO_CHANNEL = 100;

Le canal doit impérativement être identique sur la télécommande et sur tous les récepteurs.

Le canal 100 correspond à une fréquence radio de 2500 MHz.


Mesure de la batterie de la télécommande

La tension des deux accumulateurs 18650 ne peut pas être appliquée directement sur une entrée analogique de l’Arduino.

Le pont diviseur présenté lors de la fabrication utilise :

const float BATTERY_R1 = 4700.0;
const float BATTERY_R2 = 6800.0;

soit :

  • R1 = 4,7 kΩ ;
  • R2 = 6,8 kΩ.

Le programme utilise ces valeurs pour reconstruire la tension réelle de la batterie à partir de la tension mesurée sur A2.

Si les valeurs des résistances sont modifiées lors de la construction, ces deux paramètres doivent être adaptés en conséquence.


Zone morte du potentiomètre

Le potentiomètre de conduite possède une zone centrale correspondant à l’arrêt de la locomotive.

Sa largeur est définie dans Config.h :

const int DEAD_ZONE = 40;

Cette zone évite qu’une petite variation de la mesure analogique autour du point central provoque une commande involontaire du moteur.

La valeur par défaut convient au montage présenté.


Paramètres du mode MEM

Le bouton LIGHT possède deux fonctions.

Un appui court commande l’éclairage de la locomotive tandis qu’un appui long permet d’accéder à la fonction MEM.

La durée nécessaire pour reconnaître l’appui long est définie par :

const uint16_t MEM_LONG_PRESS_TIME = 1500;

La valeur est exprimée en millisecondes.

Avec la valeur par défaut, l’appui doit donc durer 1,5 seconde.

Cette durée peut être adaptée si nécessaire.


Tolérance de reprise du potentiomètre

Lorsqu’une locomotive est placée en mode MEM, sa position de commande est mémorisée.

La reprise manuelle intervient lorsque le potentiomètre revient suffisamment près de cette position.

La tolérance est définie par :

const uint8_t MEM_POT_MATCH_TOLERANCE = 5;

La valeur correspond à une tolérance de 5 %.

Ce fonctionnement évite une variation brutale de commande lors de la reprise d’une locomotive précédemment laissée en mode MEM.


Répétition des commandes MEM

La communication GTRC utilise NRFLite sans acquittement automatique des paquets radio.

Les commandes ponctuelles d’entrée et de sortie du mode MEM sont donc répétées plusieurs fois afin de réduire le risque qu’une commande soit perdue.

Les paramètres correspondants sont :

const uint8_t MEM_COMMAND_REPEAT_COUNT = 5;

const uint8_t MEM_COMMAND_REPEAT_DELAY_MS = 10;

La commande est ainsi transmise cinq fois avec un intervalle de 10 ms entre chaque transmission.

Les valeurs par défaut peuvent normalement être conservées.


Le sélecteur 12 positions permet de choisir directement une locomotive.

Chaque position produit une tension différente sur l’entrée A0.

Locomotives.cpp contient les tensions de référence correspondant aux différentes positions :

const Locomotive locomotives[LOCOMOTIVE_COUNT] PROGMEM =
{
    { 0.10, 10 },
    { 0.54, 11 },
    { 1.02, 12 },
    { 1.47, 13 },
    { 1.92, 14 },
    { 2.27, 15 },
    { 2.75, 16 },
    { 3.21, 17 },
    { 3.60, 18 },
    { 4.03, 19 },
    { 4.46, 20 },
    { 4.89, 21 }
};

Chaque ligne contient deux informations :

{ tension de référence, identifiant de la locomotive }

Par exemple :

{ 1.02, 12 }

associe la position correspondant approximativement à 1,02 V à la locomotive possédant l’identifiant 12.

Le programme mesure la tension du sélecteur puis recherche la valeur de référence la plus proche.


Les identifiants des locomotives

La configuration par défaut prévoit douze identifiants :

10
11
12
13
14
15
16
17
18
19
20
21

Chaque locomotive doit posséder un identifiant unique.

L’identifiant configuré dans son récepteur devra correspondre à celui associé à sa position dans la télécommande.

Une position du sélecteur associée à l’identifiant 12 commandera donc uniquement le récepteur configuré avec :

LOCO_ID = 12

Le principe sera détaillé dans l’article consacré au logiciel des récepteurs.


Donner un nom aux locomotives

L’écran peut afficher un nom plutôt qu’un simple numéro.

Ces noms sont également définis dans Locomotives.cpp.

Par exemple :

const char locoName0[] PROGMEM = "RUSTY";
const char locoName1[] PROGMEM = "GEMINI";
const char locoName2[] PROGMEM = "TOMY";

L’ordre des noms doit correspondre à celui des positions du sélecteur.

Le premier nom correspond donc à la première locomotive de la table, le deuxième à la deuxième, etc.

Des noms relativement courts sont préférables afin de conserver un affichage lisible sur les 128 pixels de largeur de l’écran.


Pourquoi PROGMEM apparaît-il dans le programme ?

Plusieurs tables et chaînes de caractères sont suivies du mot :

PROGMEM

L’Arduino Uno utilise un microcontrôleur ATmega328P dont la mémoire vive est relativement limitée.

PROGMEM permet de stocker certaines données constantes dans la mémoire Flash du microcontrôleur plutôt que de consommer inutilement la SRAM.

Cette technique est notamment utilisée pour les noms des locomotives et différentes données fixes.

Il est donc préférable de conserver les indications PROGMEM présentes dans le programme.


Faut-il modifier les tensions du sélecteur ?

Les valeurs présentes dans Locomotives.cpp correspondent au réseau de résistances utilisé pour fabriquer le sélecteur présenté dans l’article consacré à la télécommande.

Les résistances possèdent toujours une certaine tolérance et la tension d’alimentation n’est jamais parfaitement exacte.

Le programme ne demande donc pas d’obtenir exactement, par exemple, 1,02 V.

Il recherche la tension de référence la plus proche.

De petites différences de mesure sont ainsi parfaitement normales.

Ces valeurs n’ont besoin d’être modifiées que si le sélecteur ou le réseau de résistances utilisé est différent de celui proposé pour GTRC.


Avant de compiler le programme, quelques points méritent d’être vérifiés :

  1. le bon type de contrôleur OLED est sélectionné ;
  2. les noms des locomotives correspondent à l’installation ;
  3. chaque locomotive possède un identifiant unique ;
  4. les identifiants correspondent aux positions souhaitées du sélecteur ;
  5. le canal et l’identifiant du réseau radio n’ont pas été modifiés par erreur ;
  6. les valeurs du pont diviseur correspondent bien aux résistances installées.

Avec une télécommande construite conformément à l’article précédent, les autres paramètres peuvent normalement conserver leurs valeurs par défaut.


La télécommande utilise un Arduino Uno.

Dans Arduino IDE, sélectionner :

Outils → Type de carte → Arduino Uno

puis le port série correspondant à la carte :

Outils → Port → COMx

La commande Vérifier permet ensuite de compiler le programme sans encore le transférer dans la télécommande.

Arduino IDE affiche à la fin de la compilation l’espace occupé dans la mémoire programme et dans la mémoire dynamique.

L’utilisation de modules séparés, du mode PAGE de U8g2 et de PROGMEM permet de conserver une consommation mémoire compatible avec les ressources relativement modestes de l’Arduino Uno.


Lorsque la compilation ne signale aucune erreur, le programme peut être transféré dans l’Arduino avec le bouton Téléverser.

La carte redémarre automatiquement après le transfert.

L’écran doit alors afficher successivement les écrans d’initialisation puis l’écran principal de conduite.

Plusieurs éléments peuvent déjà être vérifiés sans aucun récepteur :

  • changement de locomotive avec le sélecteur ;
  • affichage du nom correspondant ;
  • déplacement du potentiomètre ;
  • affichage de la direction ;
  • fonctionnement de la barre de vitesse ;
  • commande LIGHT ;
  • affichage de l’arrêt d’urgence ;
  • tension de la batterie de la télécommande.

Cette première vérification permet de valider une grande partie du matériel avant même de commencer la construction des récepteurs.


GTRC possède également un mode diagnostic destiné à interroger directement une locomotive.

Pour entrer dans ce mode, le bouton d’arrêt d’urgence est maintenu pendant la mise sous tension de la télécommande.

Le sélecteur permet ensuite de choisir la locomotive à interroger.

Un appui sur LIGHT déclenche l’envoi d’une requête de diagnostic.

Lorsqu’un récepteur compatible répond, la télécommande affiche la tension de sa batterie si la mesure de batterie est activée sur cette locomotive.

Le mode diagnostic deviendra surtout utile lors de la mise en service et du dépannage des récepteurs. Son fonctionnement complet sera donc repris dans les articles consacrés aux locomotives.


La fonction MEM constitue l’une des particularités de GTRC.

Elle permet de laisser une locomotive poursuivre son fonctionnement pendant qu’une autre locomotive est sélectionnée et commandée depuis la même télécommande.

L’activation s’effectue par un appui long sur le bouton LIGHT.

La télécommande mémorise alors l’état nécessaire à la reprise de la locomotive et transmet au récepteur la commande d’entrée en mode MEM.

Lors de la reprise, le potentiomètre doit rejoindre la position mémorisée avec la tolérance configurée dans Config.h.

L’affichage indique l’état MEM ainsi que la position de commande à rejoindre.

La sécurité reste prioritaire : l’arrêt d’urgence conserve toujours la priorité sur le fonctionnement MEM.

D’autres protections sont également assurées directement par les récepteurs, notamment celles liées à la batterie ou à la durée maximale de fonctionnement en MEM. Elles seront détaillées lors de l’étude du logiciel des locomotives.


Après configuration et téléversement, la télécommande GTRC V1.0 est prête à communiquer avec les futurs récepteurs.

Malgré le nombre de fichiers constituant le logiciel, les adaptations nécessaires restent volontairement limitées.

Pour la majorité des installations, elles concernent essentiellement :

  • le type d’écran OLED ;
  • les noms des locomotives ;
  • leurs identifiants ;
  • éventuellement les paramètres liés au matériel ou au mode MEM.

Le fonctionnement interne de la radio, de l’affichage, des entrées et des différents modes peut rester inchangé.

Cette séparation entre configuration et fonctionnement du programme permet d’adapter GTRC sans avoir à modifier son architecture interne.


La télécommande est désormais construite, configurée et programmée.

L’étape suivante concerne les équipements installés dans les locomotives : les récepteurs GTRC.

Le prochain article présentera leur architecture matérielle :

  • Arduino Nano et RF-Nano ;
  • module NRF24L01 ;
  • alimentation ;
  • driver moteur ;
  • commande de l’éclairage ;
  • mesure de la tension batterie ;
  • principe de configuration propre à chaque locomotive.

L’objectif reste le même que pour la télécommande : conserver un programme commun et limiter autant que possible les adaptations à quelques paramètres clairement identifiés.