Comment lire les données d’un récepteur de radio-commande avec un Arduino ?
La class ci-dessous permet d’obtenir une plage de valeurs -configurable- image de la consigne fournie par la commande.
Testé sur les récepteurs Spektrum AR6200 et AR8000, il est toutefois possible d’adapter les constantes du fichier Header pour un équipement non standard.
Le fonctionnement de cette class est extrêmement simple. Il suffit d’indiquer le PIN d’entrée du canal et les valeurs min/max attendues.
Un inconvénient toutefois, la méthode principale fonctionne en asynchrone. En conséquence, il ne faut pas perdre de vue que chaque lecture de canal prend au minimum 2ms. On pourrait développer une version utilisant les interruptions, cependant, les Arduino UNO n’ont que 2 entrées d’interruptions prioritaires alors que les récepteurs de modèles réduits ont souvent besoin de 4 à 8 canaux.
Fichier Header:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// Cette class permet de lire une voie de recpeteur Spektrum. // // Grég(ory) VIENOT - @ArtificeBoy // v1 2015 #ifndef Spektrum_h #define Spektrum_h #include "Arduino.h" #define PERIODE 20000 // Période (en micro-secondes) du signal PWM en sortie du recepteur (20000) #define PWM_MIN 1000 // Durée de l'état haut minimal (en mili-secondes) du signal PWM en sortie du recepteur (1000) #define PWM_MAX 2000 // Durée de l'état haut maximal (en mili-secondes) du signal PWM en sortie du recepteur (2000) #define INIT_MIN 1200 // Valeur initiale de calibration pour l'état haut minimal (en mili-secondes) (1200) #define INIT_MAX 1800 // Valeur initiale de calibration pour l'état haut maximal (en mili-secondes) (1800) class Spektrum { public: Spektrum(int pinCanal, int valeurMin, int valeurMax); int lire(); // Lit la valeur du canal bool connectionEtablie; // Indique si le recepteur recoit un signal de la télécommande private: int mapCanal(int val); // Map la valeur recu du canal sur la plage specifié par valeurMin et valeurMax int _pinCanal; // Numéro de pin de l'input int _valeurMin; // Borne minimale de mappage int _valeurMax; // Borne maxiamle de mappage int valeur; // Valeur brute lue à la sortie du recepteur int calibreMin; // Plus petite valeur recue depuis le debut de la lecture int calibreMax; // Plus grande valeur recue depuis le debut de la lecture }; #endif |
PERIODE : Détermine le timeOut de le mesure pulseIn(). Il correspond à la durée d’une période PWM. Un servomoteur standard est cadencé à 50Hz. Donc la période est de 20ms.
PWM_MIN & PWM_MAX : Déterminent la durée de l’état haut du signal PWM en fonction de la position. En général, les servomoteurs requièrent 1ms pour l’état fermé (0°) et 2ms pour l’état ouvert (180°)
INIT_MIN & INIT_MAX : Déterminent les Valeurs initiales de calibration. Volontairement minimisées, elles seront auto-ajustées au fils des mesures. Cette fonctionnalité est optionnelle.
Le constructeur SPEKTRUM admets 3 paramètres:
- Le PIN (pinCanal) correspondant au canal du récepteur.
- La valeur minimale (valeurMin) attendu pour une consigne basse.
- La valeur maximale (valeurMax) attendu pour une consigne haute.
La class SPEKTRUM comporte 2 méthodes :
- lire() : déclenche la mesure de la voie.
- mapCanal() : effectue une règle de 3 entre la donnée brute reçu du récepteur et la plage de valeurs attendues.

Fichier Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include "Spektrum.h" Spektrum::Spektrum(int pinCanal, int valeurMin, int valeurMax) { pinMode(pinCanal, INPUT); _pinCanal = pinCanal; _valeurMin = valeurMin; _valeurMax = valeurMax; valeur = 0; calibreMin = INIT_MIN; calibreMax = INIT_MAX; connectionEtablie = false; } int Spektrum::lire() { { valeur = pulseIn(_pinCanal, HIGH, PERIODE); // Mesure la composante haute du signal PWM if (valeur > PWM_MIN && valeur < PWM_MAX) { // (Option) Si cohérent avec un signal PWM if (valeur < calibreMin) calibreMin = valeur; // (Option) Ajuste les valeurs de calibraiton if (valeur > calibreMax) calibreMax = valeur; // (Option) connectionEtablie = true; // (Option) Idique qu'il y a reception de donées } else { connectionEtablie = false; } return mapCanal(valeur); // Lance le mappage } } int Spektrum::mapCanal(int val) { int i = map(val, calibreMin, calibreMax, _valeurMin, _valeurMax); // Règle de 3 recues/attendues if (i < _valeurMin) i = _valeurMin; // Empèche un dépassement vers le bas if (i > _valeurMax) i = _valeurMax; // Empèche un dépassement vers le haut return i; } |
Exemple d’utilisation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include "Rover.h" #include "Spektrum.h" Spektrum voieAile(PIN_SPEKTRUM_AILE, 0, 180); // Déclaration d'une voie mappé de 0° à 180° Spektrum voieElev(PIN_SPEKTRUM_ELEV, 0, 180); // pour commander un servo (par exemple) Spektrum voieAux1(PIN_SPEKTRUM_AUX1, -100, 100); // Ici la voie AUX est mappée de -100 à +100 int valeurAileron; int valeurElevation; int valeurAux1; void setup() { Serial.begin(9600); // Démarre une liaison série } void loop() { valeurAileron = voieAile.lire(); // Lit la voie AILE valeurElevation = voieElev.lire(); // Lit la voie ELEV valeurAux1 = voieAux1.lire(); // Lit la voie AUX if (voieAile.connectionEtablie) // Optionnel { // Vérifie que la connection est établie Serial.print("Aileron:"); // et que des données ont été recu Serial.print(valeurAileron); Serial.print(" / Elevation:"); Serial.print(valeurElevation); // Affiche les valeurs via l'interface série Serial.print(" / Aux1:"); Serial.println(valeurAux1); } else { Serial.println("Spektrum non connectée"); } delay(50); } |
Super librairie !
je viens de la tester avec une télécommande Spektrum DX6i et un récepteur OrangeRX, et ça marche nickel !
Merci beaucoup pour ton travail !
Vincent
Avec plaisir 🙂
Bonjour Grégory,
Il y a un point que je ne maitrise pas, je ne sais pas où brancher mes sorties récepteur, je crois que je n’ai pas tout compris…
Merci pour votre aide
Stephan
Désolé, je viens de me rendre compte de ma bêtise….