Contrôler des servomoteurs
Forme du signal
Le signal permettant de piloter des servomoteurs est un signal PWM particulier, appelé également PPM. (voir cet article)
Le signal rectangulaire doit avoir une fréquence de 50Hz, avec un temps haut variant entre 1ms et 2ms (les extrémums peuvent varier selon le modèle de servomoteur), soit un rapport cyclique de 5% à 10%.
Le Raspberry possède 2 ports capables de générer des signaux PWM de manière « hardware ».
Bibliothèque PiGPIO
https://abyz.me.uk/rpi/pigpio/
La bibliothèque piGPIO permet :
- de contrôler un ou plusieurs Pi’s
- de générer des signaux temporisés par le matériel sur n’importe quel port GPIO (0 à 31)
- des signaux PWM
- des signaux PPM (servomoteurs)
- des signaux rectangulaires periodiques de forme quelconque
- des interruptions lorsque l’un des ports change d’état
- la lecture/écriture sur des ports et le réglage de leurs modes
- des wrappers pour les liaisons I2C, SPI et série
La bibliothèque pigpio possède des fonctions dédiées à la commande de servomoteurs :
set_servo_pulsewidth(user_gpio, pulsewidth)
avec :
user_gpio
: 0 à 31pulsewidth
:- 0 = pas de signal,
- 500 à 2500 = positions extrêmes du servomoteur (pour éviter d’endommager le servomoteur, préférer l’intervalle 1000 à 2000)
Exemple complet
import pigpio pi = pigpio.pi() pi.set_servo_pulsewidth(17, 0) # éteint pi.set_servo_pulsewidth(17, 1000) # 0° pi.set_servo_pulsewidth(17, 1500) # 90° pi.set_servo_pulsewidth(17, 2000) # 180°
Bibliothèque Wiring Pi
Site officiel de la bibliothèque Wiring Pi
(ATTENTION : Wiring Pi n’est plus maintenue depuis aout 2019)
Installation
sudo pip install wiringpi
Paramétrage
Fréquence
Avec Wiring Pi, la fréquence d’un signal PWM est calculée à l’aide de deux paramètres pwmClock
et pwmRange
, selon la formule ci-dessous :
pwmFrequency en Hz = 19.2 MHz / (pwmClock x pwmRange)
soit pour 50Hz :
pwmClock = 192 pwmRange = 2000
Les commandes permettant de régler ces paramètres sont pwmSetClock
et pwmSetRange
:
wiringpi.pwmSetClock(192) wiringpi.pwmSetRange(2000)
Rapport cyclique
Le rapport cyclique est donné par un entier entre 0 et 1024, selon la formule suivante :
rapportCyclique = 1024xtempsHaut/20
Génération du signal
La commande permettant de générer le signal est pwmWrite
:
wiringpi.pwmWrite(portGPIO, rapportCyclique)
Exemple
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from time import sleep import wiringpi ################################################################################ # Installation # sudo pip install wiringpi # Adresses (ports PHYSIQUES !) des servos wiringpi.wiringPiSetupPhys() CH_SERVO_0 = 32 # BCM 12 #CH_SERVO_1 = 33 # BCM 13 MAX_T = 0.5 MIN_T = 3.5 wiringpi.pinMode(CH_SERVO_0 , wiringpi.GPIO.PWM_OUTPUT) # set the PWM mode to milliseconds stype wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS) # Réglage du 50 Hz : f = 19 200 000 Hz / pwmClock / pwmRange wiringpi.pwmSetClock(192) wiringpi.pwmSetRange(2000) def move_servo_abs(pos = 0): """ Fait tourner le servomoteur jusqu'à la position pos (-1 à 1) """ if pos < MAX_T : pos = MAX_T elif pos < MIN_T : pos = MIN_T wiringpi.pwmWrite(CH_SERVO_0, duty) sleep(1) if __name__ == "__main__": try: while 1: pt = float(input("Position (de %s à %s) : " %(MAX_T , MIN_T))) move_servo_abs(p) except KeyboardInterrupt: print ("\nCtrl-C pressed. Program exiting...")