Samedis bénévoles spécial Arduino Workshop n°1 FICHE F3 – CONTROLER DES MOTEURS ET DIRIGER UN ROBOT SOMMAIRE 1.Contrôler des moteurs CC simples ....................................................................................................... 3 2. Le pont en H ........................................................................................................................................ 3 2.1. Le circuit SN754410 de Texas Instrument ................................................................................ 3 2.2. Le câblage du circuit ................................................................................................................. 4 2.3. Le code Arduino........................................................................................................................ 5 3. La modulation de largeur du signal (PWM ou Pulse Width Modulation). .......................................... 5 3.1. Principe de la commande PWM ............................................................................................... 6 3.2. Application................................................................................................................................ 7 4.Diriger un robot avec un joystick ......................................................................................................... 8 4.1. Anatomie d’un joystick ............................................................................................................. 8 4.2. Premiers essais ......................................................................................................................... 9 4.3. Calibrage du joystick............................................................................................................... 10 1/14 4.4. Un joystick et 8 directions ...................................................................................................... 10 4.5. Le programme de l’Arduino ................................................................................................... 11 2/14 1.Contrôler des moteurs CC simples Cette séquence se limite au contrôle des moteurs à courants continus les plus ordinaires et ne traite pas des moteurs pas à pas ni des moteurs brushless. Deux techniques sont utiles : - La commande du sens de rotation par un pont en H ; - La commande la puissance (et donc de la vitesse) par la modulation d’amplitude du signal (PWM ou Pulse Width Modulation). 2. Le pont en H Le nom de ce circuit vient de sa forme : Selon l’ouverture et la fermeture des interrupteurs, le circuit alimente ou pas le moteur. La fermeture de S1 et S4, exclusivement de S2 et S3 fait tourner le moteur dans un sens et réciproquement si on ferme S2 et S3 en ouvrant S1 et S4. Ouvrir S1 et S2 ou S3 et S4 arrête le moteur. Comme tout dispositif composé de bobinages, les effets de self à l’ouverture ou à la fermeture d’un circuit produisent des pointes de courant dommages pour l’électronique et pour le moteur. Ces courants peuvent neutralisés par des diodes. Les autres courants transitoires sont atténués par des condensateurs de filtrages. Ainsi, le dispositif « mécanique » est remplace par un circuit de commande électronique. Le pont en H peut être implémenté par des relais des transistors ou un circuit intégré dédiée. Dans le cadre de cette séquence, le circuit SN754410 de Texas Instrument et qui contient deux ponts en H sera utilisé mais il existe d’autres références, comme le LN293 ou le LN298. 2.1. Le circuit SN754410 de Texas Instrument Très peu coûteux (moins de 3 euros), ce circuit mobilise 2 PINs de l’Arduino par moteur qui peuvent consommer chacun jusqu’à 1 ampère. Les circuits dédiés au contrôle des moteurs (motor shields) sont plus performants et plus pratiques à utiliser mais nettement plus chers. A noter que ce circuit permet aussi de commander des moteurs pas à pas. La documentation complète officielle du http://www.ti.com/lit/ds/symlink/sn754410.pdf circuit (datasheet) est disponible ici : 3/14 La reconnaissance de son brochage est essentielle mais notez qu’il n’est pas si compliqué dans la mesure où chaque rangée est symétrique et correspond à un pont en H, pour le contrôle d’un moteur. 1A est la patte en entrée qui contrôle la patte 1Y en sortie qui est reliée à la borne + d’un moteur. 2A commande la patte 2Y reliée à la borne – du même moteur Même principe pour le second moteur avec 3A et 3Y et 4A et 4Y Pour aller plus vite, nous donnons le câblage et le code de l’Arduino correspondant. 2.2. Le câblage du circuit Dans tout montage de puissance (même à 2A sous 5V, il y a quand même 10W maxi), nous vous conseillons de bien séparer le circuit basse tension, celui de l’Arduino, et le circuit de puissance, celui des moteurs. Cela est vrai avec n’importe quel équipement et le circuit de l’Arduino doit être découplé si nécessaire avec des condensateurs et des résistances pour éviter tout retour de courant ou parasite. (Comme pour tout circuit le chanfrein ou l’encoche désigne le haut). Les pattes à utiliser sont - 4, 5, 12 et 13 sont à relier à la masse (GND) - 3 et 5 sont à relier au moteur 1 - 11 et 14 au moteur 2 - L’alimentation de ces deux moteurs viendra de la patte 8 et de la masse (GND). Les masses doivent être reliées - La patte 16 sera reliée au +5V de l’Arduino - 2, 7, 10 et 15 aux pattes de l’Arduino pour la commande des moteurs Un petit schéma de principe au brouillon est toujours utile : +9V +5V Arduino 8 16 2 7 Pont en H 3 SN75441 5 M1 1 4/14 2.3. Le code Arduino Le programme de l’Arduino va prendre en charge la commande des moteurs. Il implémente la table de vérité du circuit : EN HIGH HIGH HIGH HIGH LOW 1A (3A) LOW HIGH LOW HIGH Indifférent 2A (4A) HIGH LOW LOW HIGH Indifférent Fonction Tourne à droite Tourne à gauche Arrêt rapide Arrêt rapide Arrêt Après avoir déclaré les variables identifiant les PIN moteurEN12, Moteur1A et Moteur2A, la mise en marche avant d’un moteur se ferait par les 3 instructions : int MoteurEN12 = 3; int Moteur1A = 4; int Moteur2A = 5; loop() { MarcheAvant() } Void MarcheAvant() { digitalWrite(MoteurEN12, HIGH); digitalWrite(Moteur1A, HIGH); digitalWrite(Moteur2A, LOW); … idem pour le deuxième moteur } Les autres mode de marche peuvent être codés de la même façon. 3. La modulation de largeur du signal (PWM ou Pulse Width Modulation). 5/14 La commande de vitesse est réalisée en envoyant une valeur comprise entre 0 et 255 sur les pates EN du circuit (pattes1 pour le moteur 1 et 9 pour le moteur 2). Auparavant, il est utile de comprendre le principe d’une commande PWM. 3.1. Principe de la commande PWM La tension de sortie correspondant à la hauteur du signal, l’idée est de n’émettre ce signal que pendant une fraction plus ou moins importante d’un cycle. On utilise pour ce faire une variable qui contiendra la valeur du temps d’émission. Contrairement aux deux commandes précédentes pour le pont en H, cette valeur sera transmise par la fonction analogWrite(PIN, Valeur); La variation de la largeur de l’impulsion va entraîner une diminution de la valeur moyenne de la tension (Tension de sortie = durée ON/durée OFF) x Tension maxi) : 6/14 Et la précision de la commande va dépendre de la capacité d’échantillonage du signal par le processeur1 : Avec un Arduino UNO ou NANO, l’échantillonnage se fait sur 8 bits donc la valeur de puissance peut varier entre 0 et 255. Dans notre montage, le signal est émis par les PIN de l’Arduino qui permettent d’utiliser le PWM (3, 5, 6, 9, 10 et 11 sur les Arduino à base de processeurs AtMega328). 3.2. Application Un exemple très connu2 est la variation d’intensité lumineuse d’un groupe de LED de différentes couleurs pour créer une ambiance (voir la référence) Mais la commande par PWM est très utilisée pour la variation de vitesse des moteurs. En robotique de loisir, elle permet d’avoir un déplacement à plusieurs vitesses. Par exemple, un déplacement à 100% de la vitesse pour aller d’un bout à l’autre du plateau de jeu et une vitesse réduite pour l’approche d’une action de jeu. Avec le circuit SN75441, deux possibilités sont offertes pour le PWM: 1 2 - Utiliser les broches EN12 et EN34 pour envoyer un signal PWM avec la valeur correspondant à la vitesse souhaitée ; - Envoyer un signal PWM à la place du signal HIGH sur les pattes de commandes 1, 2, 3 ou 4A. http://todbot.com/blog/wp-content/uploads/2006/10/arduino_spooky_projects_class2.pdf http://todbot.com/blog/spookyarduino/ 7/14 Cette dernière solution est la plus efficace tandis que la première est plus simple. En dessous de 50% de puissance cependant, le moteur ne tourne plus. Avec une variable nommée Vitesse qui donnerait la valeur du PWM, le code serait le suivant 1ère solution 2ème Solution int MoteurEN12 = 3; int Moteur1A = 4; int Moteur2A = 5; int MoteurEN12 = 3; int Moteur1A = 4; int Moteur2A = 5; int Vitesse = 200; int Vitesse = 200; loop() { MarcheAvant() } loop() { MarcheAvant() } Void MarcheAvant() { analoglWrite(MoteurEN12, Vitesse); digitalWrite(Moteur1A, HIGH); digitalWrite(Moteur2A, LOW); Void MarcheAvant() { digitalWrite(MoteurEN12, HIGH); analogWrite(Moteur1A, Vitesse); digitalWrite(Moteur2A, LOW); … idem pour le deuxième moteur … idem pour le deuxième moteur } } 4.Diriger un robot avec un joystick Un joystick du même type que ceux que l’on retrouve sur les consoles de jeux est idéal pour diriger un robot. Une autre possibilité est dans l’utilisation de deux potentiomètres ou de deux interrupteurs, un pour chaque moteur, mais un joystick permet de diriger le robot avec une seule main (et même un seul pouce) et de laisser l’autre libre pour commander des actionneurs. 4.1. Anatomie d’un joystick Bien que très bon marché (environ 3€), ce joystick a un fonctionnement très correct. Il est composé de deux potentiomètres disposés à angle droit et d’un bouton poussoir Il se câble simplement en reliant les bornes VCC: à l’alimentation positive (5V ou 3.3V) VERT: à un PIN d’entrée analogique de l’Arduino où il indiquera la tension sur l’axe vertical. Lorsque le joystick est centré, il indique approximativement la moitié de la tension d’entrée. L’Arduino convertit en une valeur comprise entre 0 et 1023 HORIZ: idem pour l’axe horizontal SEL: pour le bouton poussoir, lors de l’appui, cette sortie est reliée à la masse (GND) GND: la masse Ce dispositif permet de nombreuses possibilités : 8/14 4.2. Premiers essais Le programme3 ci-dessous permet de tester son fonctionnement : // Thumb Joystick example // Mike Grusin, SparkFun Electronics 3/11 // This code is free, baby. Use it however you like. . // Connections de l’Arduino au joystick const int VERT = 0; // analogique donc A0 const int HORIZ = 1; // analogique donc A1 const int SEL = 2; // digital // Connecter VCC au +Vcc de l’Arduino, idem pour void setup() { pinMode(SEL,INPUT); digitalWrite(SEL,HIGH); GND. // SEL sera lu // pull-up Serial.begin(9600); } void loop() { int vertical, horizontal, select; // lecture des valeurs du joystick vertical = analogRead(VERT); horizontal = analogRead(HORIZ); select = digitalRead(SEL); // entre 0 et 1023 // entre 0 et 1023 // HIGH (1) si non appuye, LOW (0) sinon // affichage des valeurs Serial.print("vertical: "); Serial.print(vertical,DEC); Serial.print(" horizontal: "); Serial.print(horizontal,DEC); Serial.print(" select: "); if(select == HIGH) Serial.println("non appuye"); else Serial.println("APPUYE!"); } 3 https://www.sparkfun.com/tutorials/272 9/14 On remarque que lorsqu’il est au repos, la valeur renvoyée n’est pas exactement égale à 512 (le milieu de l’intervalle entre 0 et 1023) sur les deux axes, du fait de la tolérance de fabrication. On constate également qu’un petit appui fait varier les valeurs. Dans ces deux cas, les moteurs se mettraient en mouvement car une valeur différente du point de repos aurait été mesurée ou parce qu’un petit mouvement du pouce l’aurait faite varier. 4.3. Calibrage du joystick Une solution est dans la création d’une zone encadrant le point neutre et parce que chaque potentiomètre peut avoir une valeur légèrement différente, on utilise des seuils mini et maxi qui encadrent un intervalle au sein duquel le joystick est réputé être dans sa position neutre Le calibrage du joystick revient à définir un intervalle sur les X et les Y qui correspond au point neutre afin d’éviter les actions intempestives. Chaque axe une valeur de seuil mini et maxi 4.4. Un joystick et 8 directions Pour diriger le robot, on peut définir 8 directions qui donneront de la précision dans les déplacements car en avec une base mécanique à 2 roues motrices, le mouvement est contrôlé par le sens de rotation et la vitesse de chaque moteur. Le pourcentage de vitesse peut être variable selon la technique du Pulse Width Modulation (PWM). Les rotations et changement de direction peuvent être très rapides ou au contraire plus progressifs : Pour coder le changement de direction dans le programme Arduino, on utilise un couple de variables x et y : Avant X Avant gauche 1 Avant droite Gauche 0 -1 1 (1 ;1) (0 ; 1) (-1,1) 0 (-1 ;0) (0 ; 0) (1,0) -1 (1 ;-1) (0 ; -1) (-1,-1) Droite Y Arriere gauche Arrière droite Arrière 10/14 La position médiane (0, 0) sera contrôlée par les valeurs de seuils utilisées pour le calibrage et à chaque itération de la boucle loop(), x et y seront remis à 0. C’est le changement de valeur de x et y causé par un changement de valeur des potentiomètres qui permettra de déclencher le mouvement ad hoc. Notez bien que sur l’axe X la valeur la plus à gauche est 1023 et la plus à droite 0 ! 4.5. Le programme de l’Arduino 4.5.1. Déclaration des PINs, des variables et des constantes On déclare les deux PINs rattachés aux bornes VERT et HORIZ du joystick : Puis les variables X et Y qui seront utilisées pour la lecture sur ces PINs : Des constantes de seuil encadrant le point mort théorique (512) : et deux variables qui permettront de réduire les valeurs lues sur les deux potentiomètres (de 0 à 1023) à 9 couples de valeurs : 4.5.2. Initialisation : Setup() Il n’y a rien de particulier pour la gestion du joystick dans le setup ! 4.5.3. Boucle principale : Loop() A chaque cycle, on lit la valeur des deux potentiomètres HORIZ et VERT : Et on remet à 0 les variables de direction (les moteurs sont arrêtés) On calcule la valeur de la direction sur X : 11/14 Et sur Y : On obtient un couple de valeur (x-direction ; y_direction) qui correspond au tableau ci-dessus et qu’i suffit de tester pour déterminer l’action à réaliser. On note la fonction ARDroite() qui va commander les moteurs de façon à obtenir un déplacement en arrière et vers la droite selon le tableau décrit plus haut : void ARDroite() { digitalWrite(M1_SENS_AR, digitalWrite(M1_SENS_AV, digitalWrite(M1_VITESSE, digitalWrite(M2_SENS_AR, digitalWrite(M2_SENS_AV, digitalWrite(M2_VITESSE, } HIGH) ; LOW; HIGH) ; HIGH) ; LOW) ; 128) ; // // // // // // controle sens controle sens vitesse 100% controle sens controle sens vitesse 50% AR AV AR AV 4.5.4. Le test de direction : version complète Les 9 positions possibles sont gérées par une imbrication de tests conditionnels dans une structure de type si <condition> alors <bloc1> sinon <bloc2>. Si x_direction = -1 Alors Si y_direction = -1 Alors ARDroite() (-1 ; -1) Sinon Si y_direction = 0 Alors ADroite() (-1 ;0) Sinon AVDroite() car y_direction vaut 1 donc (-1 ;1) FinSI FinSi Sinon 12/14 - Si x_direction = 0 Alors Si y_direction = -1 Alors Marche AR (0, -1) Sinon Si y_direction = 0 Alors STOP() (0 ; 0) Sinon MarcheAV() (0 ; 1) FinSi Sinon (x_direction = 1) Si y_direction = -1 Alors ARGauche() (1, -1) Sinon Si y_direction = 0 Alors AGauche() (1 ; 0) Sinon AVGauche() (1 ;1) FinSi FinSi FinSI FinSi FinSi 4.5.5. Le test de direction : version sumplifiée En ne retenant que 4 directions et en testant les conditions deux par deux pour ne retenir que les couples du tableau, les tests se simplifient : Si x_direction = 0 et y_direction = 0 alors STOP() FinSi Si x_direction = 0 et y_direction = 1 alors MarcheAV() FinSi Si x_direction = 0 et y_direction = -1 alors MarcheAR() FinSi Si x_direction = 1 et y_direction = 0 alors ADroite() FinSi Si x_direction = -1 et y_direction = -0 alors AGauche() FinSi 13/14 * * * 14/14