Accessories permet de piloter finement tous vos accessoires, qu’il s’agisse de moteurs rotatifs ou linéaires, de servos, de moteurs pas à pas, de solénoïdes ou de DELs et ce quel que soit le type de circuit d’alimentation utilisé. Des fonctions basiques et communes à tous les types d’accessoires rendent son utilisation très simple. La gestion de groupes de DEL ou de moteurs est aussi possible...
Bibliothèque Accessories (1)
Les grands principes
. Par :
. URL : https://www.locoduino.org/spip.php?article178Petite info pour les utilisateurs de Universal Accessory Decoder, ou UAD pour les intîmesAccessories n’est pas juste un copié/collé de Un décodeur d’accessoires universel (1) dont on aurait retiré la partie Commanders : de gros changements structurels sont intervenus dans cette revisite. Ils ont été inspirés par la volonté de rendre l’utilisation de la bibliothèque la plus simple et la plus compréhensible possible, grâce à la disparition quasi totale du recours à des pointeurs, à la disparition des ’Drivers’ utilisant des ports, remplacés par les ports eux même, et au recours systématique à des constructeurs sans arguments puis à des ’begin’ à peu près identiques. Outre la simplicité, le gain concerne également la mémoire utilisée, dorénavant presque intégralement rapportée par le rapport de fin de compilation de l’IDE, et moins chargée grâce à la disparition des Drivers.Dernier avantage et pas des moindres, UAD fournissait un certain nombre (assez réduit) de drivers : relais, shield L293D, L298N et Arduino. En dehors de ces circuits, point de salut. Accessories a choisi de se détacher de cette contrainte en proposant à son utilisateur de définir lui même les ports nécessaires en fonction de sa configuration. Cela permet de virtuellement adresser n’importe quel circuit de puissance, et même de câbler un circuit classique en dehors de son utilisation normale, comme de brancher une DEL ou un servo sur une des sorties d’un LMD18200 au lieu d’un moteur ! Un retour silencieux et involontaire vers l’universalité ?Mais revenons à nos moutons et faisons comme si on ne connaissait pas UAD...
Pourquoi Accessories ?
Le but de cette bibliothèque est de faire bouger ou d’illuminer vos accessoires. Ces petites choses étant quelquefois un peu trop dispendieuses, il faut souvent intercaler un circuit de puissance entre l’Arduino et eux. Ce circuit va transmettre grâce à une alimentation extérieure une puissance beaucoup plus importante que ce que le petit Arduino pourrait délivrer. L’Arduino est donc relié aux entrées de pilotage du circuit, tandis que l’accessoire est connecté aux sorties de puissance du circuit.
Les classes
Accessories regroupe deux grandes familles d’objet : les accessoires et les ports.
Accessoires
Là encore, division en deux sous-familles : les moteurs (les choses qui bougent), et les DELs (les choses qui brillent...).
AccessoryMotorOneWay avec durée d’activation
Moteurs à mouvement ponctuel
Typiquement, on parle là des moteurs d’aiguillage Kato ou de rails de découplage. Dotés d’un seul solénoïde, ils doivent être activés sur une durée limitée pour ne pas griller. Surtout que cette technologie implique souvent une consommation électrique assez importante... Certains sont heureusement équipés de contacts de fin de course qui coupent l’alimentation une fois le déplacement terminé.
AccessoryMotorTwoWays avec limite de durée
Moteurs à mouvement ponctuel dans deux directions
Rentrent dans cette catégorie tous les moteurs qui nécessitent deux fils d’alimentation. Ils sont dotés de deux solénoïdes comme la plupart des aiguillages classiques, à part Kato. Ils ont deux directions possibles et sont limités dans le temps, mais leur vitesse est réglable, tout comme la direction du mouvement.
AccessoryMotorOneWay sans limite de durée
Moteurs à mouvement continu
Ce sont des moteurs utilisés pour des animations, comme un moulin ou une roue de fête foraine, ou alors pour un ventilateur de confort...
Ces moteurs n’ont qu’un sens de fonctionnement possible et ne sont pas limités dans le temps, mais leur vitesse est souvent réglable.
AccessoryMotorTwoWays sans limite de durée
Moteurs à mouvement continu
Ce sont des moteurs similaires à ce que l’on trouve dans nos engins moteur. Ils ont deux directions possibles et ne sont pas limités dans le temps. Leur vitesse est éventuellement réglable.
AccessoryServo
Servo moteur
Très utilisés dans le monde modéliste pour l’aviation, la marine et les voitures, ils sont aussi utiles pour nos trains comme moteurs lents pour les aiguillages ou les passages à niveau. Ils disposent d’une course rotative souvent réduite à moins d’un demi tour, et peuvent se déplacer à une position particulière au degré près.
AccessoryStepper
Moteurs pas à pas
Ces moteurs rotatifs au placement très précis permettent de piloter essentiellement des plaques tournantes, des ponts secteur ou des ponts transbordeurs. Ils peuvent se déplacer à différentes vitesses vers une position particulière et disposent d’un débattement intégral : un tour complet ne leur fait pas peur ! Le nombre de positions atteignables est fixé par la mécanique du moteur et le besoin de précision doit conditionner son choix au moment de l’achat.
- Des moteurs pas à pas, dont en haut à gauche le célèbre 28BYJ-48 économique et très fréquent autour de l’Arduino...
AccessoryLight
Une DEL
Là, c’est un peu plus simple. Une DEL peut s’allumer ou s’éteindre. Une nuance apparaît si l’on veut utiliser un allumage ou une extinction progressifs, si l’on veut faire clignoter.
AccessoryLightMulti
Un groupe de DEL
Il s’agit d’un groupe de DELs, comme un feu de signalisation ou un éclairage urbain. L’activation se fait à partir de motifs (’pattern’ dans la langue de Sir Sean Connery) qui décrivent les DELs allumées, les DELs éteintes, et éventuellement celles qui clignotent !
Ports
Le port constitue l’interface entre l’Arduino et le circuit de puissance cité plus haut. Quand un regain de puissance n’est pas nécessaire, il est directement l’interface entre l’Arduino et l’accessoire lui même (DEL ou servo-moteur...) !
Cet objet détient les broches utilisées, ainsi que la manière de les utiliser. Selon l’accessoire à piloter et le circuit de puissance utilisé, le type de port peut changer.
PortOnePin
C’est le port le plus simple : un broche commandée en digital ou en PWM. C’est celui à utiliser pour un accessoire à un seul fil de commande, par exemple une DEL ou un moteur type solénoïde simple (rail dételeur, aiguillage Kato...). C’est aussi celui à utiliser si l’on veut piloter un relais ou un transistor.
PortTwoPins
Deux broches en digital ou en PWM, à utiliser pour les moteurs rotatifs dont la direction est donnée par la polarité, ou les moteurs d’aiguillage à double solénoïde en n’oubliant pas de préciser une durée de fonctionnement.
PortTwoPinsEnable
Certains circuits de puissance ont besoin d’une broche supplémentaire ’Enable’ qui, comme son nom l’indique dans la langue de George Clooney, lance ou pas l’alimentation de ce qui est connecté sur les deux autres fils. Selon le circuit alimenté, les broches principales peuvent être digitale ou PWM, et la broche ’Enable’ supplémentaire peut aussi être configurée digitale ou PWM. Elle fixe la vitesse du moteur dans ce dernier cas.
PortSpeedDirBrake
D’autres circuits, comme le LMD18200, fonctionnent avec une broche en PWM qui fixe la vitesse du moteur, une broche ’Dir’ qui donne le sens de rotation, et ’Brake’ qui active ou pas l’alimentation.
PortServo
Un servo se pilote avec une seule broche digitale, mais il a besoin d’une gestion particulière. C’est pourquoi PortOnePin n’est pas utilisable. Des fonctions spéciales lui sont dédiées et permettent de déplacer précisément le moteur.
PortStepper
Là encore, un stepper (ou moteur pas à pas dans la langue de Joey Starr), a besoin d’un comportement particulier lié à sa technologie. Les moteurs à deux fils et à quatre fils sont possibles. Le deux-fils n’est pas testé, je n’en avais pas sous la main !
La difficulté dans ces moteurs concerne les phases qui doivent être envoyées dans un ordre précis pour le déplacer. L’ordre doit être le bon, sinon ça tourne quand même, mais un peu n’importe comment ! C’est ce qui a motivé l’argument optionnel permettant de fixer la bonne séquence d’envoi. La valeur par défaut correspond à ce qui est nécessaire pour faire bouger le fameux moteur économique 28BYJ48 que l’on trouve dans tous les kits de démarrage Arduino, ou pour pas cher sur la baie. A noter, la librairie ’stepper’ livrée avec l’IDE Arduino ne convient pas à ce petit moteur !
PortShieldL293d
Ce type de port est dédié au shield L293d. Ce composant possède quatre sorties pour deux moteurs classiques, ou un moteur pas à pas. La puissance est limitée à 0.6A par canal. Ce shield, remplacé depuis par d’autres plus performants, est disponible à moins de dix euros au pays de Mao. Sur un Uno il interdit tout autre shield au-dessus de lui. Sur un Méga, certaines broches analogiques et digitales restent accessibles, mais aucune capable de faire du PWM...
Ce sont donc quatre ports de type PortShieldL293d, plus deux ports de type PortServo utilisant forcément les broches 9 et 10, qui sont disponibles. Deux ports pour moteurs pas à pas peuvent remplacer les quatre moteurs classiques.
Oui mais quoi ?
C’est vrai ça, comment choisir le bon port ?
Accessoire | OnePin | TwoPins/Enable | SpeedDirBrake | Servo | Stepper |
---|---|---|---|---|---|
DEL | x | ||||
Dételeur | x | ||||
1 solénoïde | x | ||||
2 solénoïdes | x | ||||
Moteur | x | x | |||
Servo | x | ||||
Stepper | x |
Le premier choix concerne le type d’accessoire. Pour un servo, pas d’autre choix que PortServo. Pour un stepper, même absence de choix, ce sera PortStepper !
Reste les DEL et les moteurs classiques. Normalement, une DEL, un rail dételeur ou un aiguillage Kato n’ont besoin que d’un seul fil, c’est donc un PortOnePin.
Pour un moteur à un solénoïde, on peut également utiliser un PortOnePin. Pour les moteurs à deux solénoïdes comme les aiguillages courants, c’est PortTwoPins.
Pour les autres, le mieux est de regarder comment l’accessoire doit être raccordé à son alimentation. Une broche PWM, une broche digitale, deux ? Une broche Enable ? Des broches Dir, Brake ? Le choix sera fait selon le mode de branchement réclamé par le circuit de puissance...
Comment ça marche ?
Les principes
Accessories fonctionne sur la base d’ordres reçus qui vont déclencher des comportements des accessoires déclarés. Les ordres peuvent être donnés depuis un bouton codé localement en utilisant des fonctions basiques comme n’importe quel programme Arduino commun, ou via des événements interprétés par ces mêmes accessoires.
Evénements
Tout comme dans la Bibliothèque Commanders, chaque accessoire est activé par un événement qui lui est destiné. Les événements ont exactement la même forme : un identifiant qui est un entier long non signé (entre 0 et 4 294 967 295 !), un type extrait de l’enum ACCESSORIES_EVENT_TYPE, copie conforme de l’enum COMMANDERS_EVENT_TYPE de la bibliothèque Commanders, et un entier signé donnant une info supplémentaire, comme la position à atteindre...
Chaque accessoire se voit doté d’un ou plusieurs identifiants. Si l’événement reçu le concerne, il tentera d’effectuer ce qui est demandé par le type, éventuellement aidé par l’info en plus.
Plus concrètement, prenons l’exemple d’un servo moteur. Quatre positions ont été définies pour lui, chacune identifiée par un code et une position absolue : 100 à 10°, 101 à 20°, 102 à 45° et 103 à 160°. Si un événement est reçu avec comme identifiant l’un des quatre déclarés par le servo (100, 101, 102 ou 103), selon le type d’événement la réaction sera différente :
- ACCESSORIES_EVENT_TOGGLE demande au servo moteur de passer à la position suivante parmi les quatre déclarées : le servo passera de la position courante, par exemple 102, à la position suivante : 103. Arrivé à la dernière position, il recommence au début, à 100.
- ACCESSORIES_EVENT_MOVEID demande au servo de se déplacer à la position identifiée : par exemple si l’id est 102 alors il ira à 45°.
- ACCESSORIES_EVENT_MOVEPOSITION demande au servo de se déplacer directement à la position demandée par l’info supplémentaire, probablement un angle entre 0 et 180°, et ce quel que soit l’identifiant utilisé.
Pour un moteur rotatif classique, on va plutôt utiliser l’événement ACCESSORIES_EVENT_MOVE, là encore copie conforme de l’enum COMMANDERS_EVENT_MOVE, avec l’info supplémentaire à la valeur de l’enum ACCESSORIES_MOVE_TYPE, de ACCESSORIES_MOVE_ON ou OFF pour le mettre en marche ou l’arrêter.
Fonctions de base
Il n’est pas obligatoire d’utiliser les événements pour activer un accessoire. Chaque type d’accessoire dispose d’un jeu de fonctions dédiées qui permettent de faire la même chose. Par exemple pour une DEL, les fonctions LightOn, LightOff ou Blink sont disponibles... Pour un moteur , on parlera de MoveLeftDir, MoveRightDir et MoveStop.
Au final, que l’on passe par un événement ou une fonction basique, l’Arduino va demander au port d’activer ou désactiver la(les) bonne(s) broche(s), et ainsi mettre en route ou arrêter l’accessoire qui lui est relié physiquement...
l’EEPROM
Accessories va faire la sauvegarde de l’état de tous les accessoires dans la mémoire EEPROM de l’Arduino. Il suffit de lui dire depuis quelle adresse et sur quelle plage mémoire la sauvegarde peut se faire (Accessories.::begin(10, 500);
), et à chaque changement d’état d’un accessoire la nouvelle configuration sera sauvée. Pour ceux que ça ne branche pas, un simple Accessories::begin();
sans argument fera fonctionner la bibliothèque sans la sauvegarde.
Si la sauvegarde a été faite, au redémarrage de l’Arduino, il ira seul remettre tout en place : les lumières reprendront leur état : éteintes, allumées ou clignotantes, les moteurs se rappelleront de leur dernière position et de leur vitesse à ce moment là. Les servos retrouveront leur position, tout comme les moteurs pas à pas. C’est d’autant plus important pour ces derniers parce qu’ils n’ont pas de repère absolu, pas de valeur zéro. Et leur position n’est pas mesurable...
La sauvegarde utilise le principe de la classe CircularBuffer décrite dans la Bibliothèque EEPROMextent, mais sans utiliser la bibliothèque. Cette classe permet d’optimiser la sauvegarde en écrivant à une place différente à chaque fois et ainsi minimiser l’usure de l’EEPROM. Cet emplacement sera forcément compris en 10 et 510 dans notre exemple. soit à partir de l’adresse de début 10, et en utilisant au maximum l’espace de 500 octets proposé. D’autres sauvegardes utilisant EEPROM.write ou EEPROM.update seraient possibles pour d’autres usages avant 10 et au delà de 510.
Enfin, si la bibliothèque devait être mise à jour sur cet Arduino, ou si le nombre d’accessoires devait changer, la sauvegarde serait perdue. Ceci afin de préserver l’intégrité des accessoires pilotés. Il vaut mieux repartir d’un état de démarrage que d’essayer d’envoyer tous les moteurs sur la lune parce les données lues ne correspondent plus a ce qui a été sauvé !
L’avenir
Une bibliothèque comme Accessories promet de n’être jamais terminée ! D’autres accessoires se profilent déjà, comme les DEL multicolores RGB WB2812. D’autres types de port aussi avec le traitement des multiplicateurs de port comme les 74HC595 en digital ou le PCA9685 en PWM. Bref, encore du pain sur la planche...
La bibliothèque
[1]
Optimisations
On le sait, l’Arduino est une plateforme puissante et passionnante, mais qui manque cruellement de mémoire. Une bibliothèque comme celle ci, qui tente d’unifier des comportements disparates en offrant de multiples fonctionnalités est confrontée tôt ou tard à des problèmes de compatibilité et de mémoire.
Dans le fichier Accessories.h qui se trouve dans le répertoire de la bibliothèque elle même, vous verrez :
//#define NO_GROUP
//#define NO_MOTOR
//#define NO_SERVO
//#define NO_STEPPER
//#define NO_LIGHT
//#define NO_SHIELDL293D
//#define NO_EEPROM
Cette litanie de #define NO_
est là pour vous permettre d’exclure définitivement des parties de la bibliothèque qui ne vous sont pas utiles à l’instant T. Enlevez le ’//’ devant le #define NO_STEPPER
, et tout le code correspondant aux moteurs pas à pas sera purement et simplement éliminé de la compilation ! Le compilateur tente bien de faire ce travail tout seul, mais il peut échouer dans certains cas particuliers. Vous gagnerez ainsi un peu de mémoire programme, et peut être aussi un peu de mémoire dynamique, mais pas forcément.
L’autre usage concerne l’emploi de bibliothèques extérieures qui ne sont pas toujours présentes. Ce n’est pas le cas dans Accessories, mais on est pas à l’abri d’une évolution...
Le NO_EEPROM quant à lui évite de surcharger le code avec la sauvegarde sur EEPROM si elle n’est pas nécessaire.
La mise au point
C’est toujours difficile sur un Arduino de trouver la ligne qui fait que rien ne se passe comme prévu... J’ai inclus deux mécanismes pour aider a faire marcher le programme.
Dans le fichier Accessories.h qui se trouve dans le répertoire de la bibliothèque elle même, dans les toutes premières lignes, vous verrez :
//#define ACCESSORIES_DEBUG_MODE
Retirez les deux ’//’ qui représentent le début d’un commentaire. En faisant cela, vous verrez apparaître sur la console série (si elle est initialisée avec une vitesse comme Serial.begin(115200);
) tout un tas de messages d’initialisation, et éventuellement d’erreur. Avant de passer à la suite corrigez ces erreurs, inutile d’aller plus loin si Accessories lui même vous signale des problèmes ! Pendant l’exécution, vous verrez aussi passer des messages vous informant du fonctionnement de la bibliothèque : activation d’un accessoire, réception d’un événement, etc...
Je vous ai mis à disposition une fonction PrintEvent qui formatte et affiche un événement sur la console... Utile pour savoir si Accessories a bien reçu l’ordre voulu, quel que soit le canal d’envoi.
Ces affichages augmentent considérablement la taille du programme et affectent aussi un peu sa vitesse. Avant de mettre l’Arduino en production, il vaut mieux penser à remettre le ’//’ à sa place pour revenir à un programme léger et réactif ! D’ailleurs il peut arriver que j’oublie de remettre le ’//’ avant de construire le .zip de la bibliothèque. Normalement en fonctionnement, Accessories n’envoie strictement rien sur la console. Donc si vous voyez apparaître le Copyright et d’autres choses, remettez le ’//’ en place !
Où ça se passe...
La plupart de mes bibliothèques, comme Accessories, Commanders ou DIO2, sont maintenant référencées par l’IDE Arduino. Cela implique que pour les installer, il vous suffit de demander à l’IDE via sa commande ’Gestionnaire de bibliothèques’ de les trouver.
Sinon, la bibliothèque est disponible ici sous sa forme brute : Forge Locoduino. Si vous l’installez vous même, pensez à renommer le répertoire d’installation en ’Accessories’ et pas ’Accessories-master’ !
Notez qu’un fois intallée, vous trouverez dans le répertoire ’extras/Doc’ une documentation html visible sur n’importe quel système avec n’importe quel navigateur un peu moderne. Cette documentation reprend en Anglais l’ensemble des informations données ici et détaille plus précisément les rôles de chaque classe, de leurs fonctions et de leurs arguments. Sous Windows pour la lancer, il suffit de double cliquer sur le fichier StartDoc.bat présent dans le répertoire de la bibliothèque, sinon il faut manuellement double-cliquer sur le fichier ’extras/Doc/index.html’ . La page ’Revision History’ donne la liste des versions et les changements apportés en français et en anglais !
Accessories utilise une autre bibliothèque, appelée DIO2, qui gère des accès plus rapide aux broches qu’avec les fonctions natives de l’Arduino. Son usage est transparent pour l’utilisateur de Accessories, mais nécessaire pour réduire les temps de traitement. Cette bibliothèque annexe est disponible dans le répertoire ’extras’ présent avec les sources de la bibliothèque Accessories. Elle est également disponible sur la Forge Locoduino.
Dans le prochain article de la série, nous verrons ce qui différencie un croquis Accessories de son équivalent sans bibliothèque, puis nous étudierons quelques cas réels dans le détail pour mieux comprendre les rouages de son usage. Je compte aussi sur vous amis lecteurs pour me soumettre ici ou sur le forum des idées de réalisations concrètes qui pourraient nous servir d’exemples pour tout le monde !
[1] Le fin de l’article est très similaire à ce que j’ai déjà écrit pour Commanders, ne soyez pas surpris !