Accueil > GNU/LINUX & RASPBERRY PI > Commande d’un servo moteur avec raspberry pi et la bibliothèque (...)

Commande d’un servo moteur avec raspberry pi et la bibliothèque WiringPi-python

mercredi 7 décembre 2016, par thebault

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").

PNG - 10.3 ko
Source : Wikipedia

Branchements

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.

JPEG - 305.3 ko
JPEG - 543.5 ko

Programme en python

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 fonctiondescription
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 fonctiondescription
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)

  • le mode "balanced" : la fréquence n’est pas constante, ce qui peut poser problème lors de la commande d’un moteur ou d’une led...
  • le mode "M/S" : c’est le mode que l’on utilisera car la fréquence est constante

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 fonctiondescription
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)

  • pwmFrequency = fréquence des signaux PWM
  • pwmClock = diviseur du signal d’horloge
  • pwmRange = plage de variation du code du rapport cyclique (Par défaut, on a pwmClock=33, et pwmRange=1024.)

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 impulsioncode rapport cyclique
1 ms 51
1.5 ms 77
2 ms 102

servo1.py  : permet de placer le servomoteur en position centrale

  1. import wiringpi
  2.  
  3. wiringpi.wiringPiSetupPhys()
  4. wiringpi.pinMode(32,2)
  5.  
  6. wiringpi.pwmSetMode(0)
  7. wiringpi.pwmSetRange(1024)
  8. wiringpi.pwmSetClock(375)
  9.  
  10. wiringpi.pwmWrite(32,77)

Télécharger

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) :

  1. import wiringpi
  2.  
  3. wiringpi.wiringPiSetupPhys()
  4. wiringpi.pinMode(32,2)
  5.  
  6. wiringpi.pwmSetMode(0)
  7. wiringpi.pwmSetRange(1024)
  8. wiringpi.pwmSetClock(375)
  9.  
  10. while True :
  11. wiringpi.pwmWrite(32,51)
  12. wiringpi.delay(1000)
  13. wiringpi.pwmWrite(32,77)
  14. wiringpi.delay(1000)
  15. wiringpi.pwmWrite(32,102)
  16. wiringpi.delay(1000)

Télécharger

Pour l’exécuter : sudo python servo1.py

Portfolio

SPIP | | Plan du site | Suivre la vie du site RSS 2.0
Habillage visuel © digitalnature sous Licence GPL