Accueil > GNU/LINUX & RASPBERRY PI > Commande d’un servo moteur avec raspberry pi et la bibliothèque (...)
mercredi 7 décembre 2016, par
Les servomoteurs de modélisme sont des systèmes asservis dans lesquels la position angulaire de l’axe de sortie est commandée par une impulsion dont on va faire varier la durée. En général, la durée de l’impulsion va varier de 1 ms à 2ms pour une position de 0° à 180°. Cependant, d’un modèle à l’autre ces valeurs peuvent varier de façon importante.
Pour une présentation détaillée : Servomoteur (wikipedia) ou http://eskimon.fr/287-arduino-602-un-moteur-qui-de-la-tete-le-servo-moteur
Le raspberry pi est équipé de 2 sorties PWM : broche 32 (BCM18) et broche 33 (BCM 27) que l’on peut utiliser pour commander des servomoteurs.
Alors qu’un signal PWM a un rapport cyclique qui varie de 0 à 1 ( c’est à dire une largeur d’impulsion de 0 à 20 ms, soit la totalité de la période -pour une fréquence de 50hz -), la commande d’un servomoteur doit être limitée à des impulsions de 1 ms à 2 ms ("théorique").
Il vaut mieux utiliser une alimentation externe réglée sur 5V à 6V ( ou piles) car si on se branche sur une des sorties 5V du GPIO, le raspi n’est pas toujours capable de fournir l’intensité nécessaire au servomoteur et risque de "rebooter" violemment.
Pour cela, j’utilise la bibliothèque wiring-pi car elle permet d’utiliser les PWM hardware des cartes raspberry alors que les autres bibliothèques comme RPi.GPIO utilisent des PWM "software" qui provoque du "jitter" (imprécisions, tremblements du servo).
Pour installer la bibliothèque Wiring-pi et comprendre son fonctionnement, voir la page http://gilles.thebault.free.fr/spip.php?article44, particulièrement le chapitre sur les sorties PWM.
Pour appeler la bibliothèque :
Nom de la fonction | description | |
---|---|---|
import wiringpi | On appelle la bibliothèque wiringPi |
Pour initialiser la bibliothèque, on a 3 choix pour nommer les broches du connecteur :
Nom de la fonction | description | |
---|---|---|
wiringpi.wiringPiSetup() | On utilise la numérotation des broches propre à la bibliothèque | |
wiringpi.wiringPiSetupGpio() | On utilise la numérotation des broches suivant les noms des E/S du GPIO Broadcom | |
wiringpi.wiringPiSetupPhys() | On utilise la numérotation des broches suivant l’ordre des broches sur le connecteur "physique" P1 du raspberry |
Pour voir les broches en ligne :http://pinout.xyz/
Dans la suite, j’utiliserai la numérotation "physique".
Le raspberry peut avoir 2 modes de fonctionnement (cf datasheet p139)
Pour commander le servomoteur, il nous faut une fréquence de 50hz (soit une période de 1/50=20ms). Les fonctions dont nous disposons pour les commandes PWM sont :
Nom de la fonction | description | |
---|---|---|
wiringpi.pinMode(n,2) | Sortie n en PWM (il y a 2 sorties PWM sur raspberry pi à partir du B+) | |
wiringpi.pwmSetMode(0) | mode M/S | |
wiringpi.pwmSetClock(pwmClock) | modifie la valeur du diviseur pwmClock | |
wiringpi.pwmSetRange(pwmRange) | modifie la valeur du code max du rapport cyclique | |
wiringpi.pwmWrite(n,rapport cyclique) | commande la sortie PWM sur la broche n, avec un rapport cyclique compris entre 0 et 1024 |
Pour avoir une fréquence fixe, on utilisera le mode M/S.
Calcul de pwmClock et pwmRange pour une fréquence de 50hz (période de 20ms)
La fréquence des sortie PWM est définie par la relation : pwmFrequency en Hz = 19.2 MHz / (pwmClock x pwmRange)
On a donc pwmClock x pwmRange=19 200 000/50=384 000.
Sachant que pwmRange=1024 par défaut, on obtient pwmClock=375
Calcul des valeurs de rapport cyclique (codé entre 0 et 1024)
On sait que pour un code de rapport cyclique de 1024, on a une durée d’impulsion de 20ms. par conséquent, si on souhaite une impulsion de durée 1.5 ms, on aura :
code rapport cyclique=1024x1,5/20=77 environ.
Quelques valeurs typiques pour les servomoteurs :
durée impulsion | code rapport cyclique | |
---|---|---|
1 ms | 51 | |
1.5 ms | 77 | |
2 ms | 102 |
servo1.py : permet de placer le servomoteur en position centrale
import wiringpi wiringpi.wiringPiSetupPhys() wiringpi.pinMode(32,2) wiringpi.pwmSetMode(0) wiringpi.pwmSetRange(1024) wiringpi.pwmSetClock(375) wiringpi.pwmWrite(32,77)
Pour l’exécuter, il faut passer en mode superutilisateur :
sudo python servo1.py
servo2.py : permet d’alterner les positions du servomoteur (gauche , centre, droite). Il est nécessaire d’utiliser une temporisation pour laisser le temps au moteur de faire le déplacement. J’utilise la temporisation issue de la bibliothèque wiringpi (1 seconde) :
import wiringpi wiringpi.wiringPiSetupPhys() wiringpi.pinMode(32,2) wiringpi.pwmSetMode(0) wiringpi.pwmSetRange(1024) wiringpi.pwmSetClock(375) while True : wiringpi.pwmWrite(32,51) wiringpi.delay(1000) wiringpi.pwmWrite(32,77) wiringpi.delay(1000) wiringpi.pwmWrite(32,102) wiringpi.delay(1000)
Pour l’exécuter : sudo python servo1.py