Le module PCA9685 est un contrôleur 16 canaux qui permet de piloter 16 sorties PWM via la communication I2C. Il permet entre autre de libérer des entrées sorties de votre microcontrôleur et piloter jusqu’à 16 LED ou servomoteurs (ou tout autre module prenant en entrée un signal PWM) à l’aide de deux broches (SCL et SDA) tout en conservant les broches de votre microcontrôleur pour d’autres modules comme des capteurs. Le Raspberry Pi est un microcontrôleur avec un modules Bluetooth et Wifi intégrés. Très simple d’utilisation il est léger et possède une capacité de mémoire et de calcul supérieure aux Arduino. Nous allons voir dans ce tutoriel comment piloter plusieurs servomoteur avec un Raspberry Pi et un module PCA9685.
Prérequis : Configuration du Raspberry Pi en I2C
Matériel
- Ordinateur
- RapsberryPi3 B+ configuré avec un OS linux et Python3
- Module PCA9685
Principe de fonctionnement
Le module est basé sur le contrôleur PCA9685 qui permet de piloter des sorties PWM à l’aide de la communication I2C et d’une horloge intégrée. Ce module comporte 6 ponts permettant de sélectionner l’adresse de la carte et ainsi de placer sur le même bus jusqu’à 62 contrôleurs pour un total de 992 servomoteurs (Adresses disponibles 0x40 à 0x7F).
Il permet de piloter des sorties PWM avec une fréquence ajustable et avec une résolution de 12 bits. Le module est compatible avec les microcontrôleurs 5V et 3.3V.
Schéma
Le Raspberry Pi possède des broches réservées pour la communication I2C (GPIO2/GPIO3).
Le module est muni d’un bus I2C et d’un entrée de puissance. Le bus I2C est branché comme suit:
- Broche GPIO3 ou SCL à la broche SCL du module
- Broche GPIO2 ou SDA à la broche SDA du module
- Broche 5V à la broche Vcc du module
- Broche GND à la broche GND du module
Dans ce tutoriel, nous utilisons la carte Raspberry Pi Zero mais il peut être adapté à d’autre microcontrôleur. Il suffit pour cela d’adapter les broches I2C disponibles sur le microcontrôleur en question et éventuellement le code.
Configuration du Raspberry Pi
Avant de pouvoir utiliser le port I2C du Raspberry Pi, il vous faut l’activer dans l’outil de configuration. Dans un terminal, entrée la commande
raspi-config
Sur l’interface, sélectionnez « 5 Interfacing Options »
Puis activez la communication en sélectionnant « P5 I2C »
Code
Installation de la librairie
Pour utiliser le module PCA9685 nous utilisons la librairie adafruit_servokit.h. Cette libraire n’est pas présente par défaut dans l’installation de Python. Pour l’installer, il vous suffit d’ouvrir un terminal et d’entrer la ligne de commande suivante.
sudo pip3 install adafruit-circuitpython-servokit
Script Python
Les largeurs de PWM généralement données en microsecondes sur une période de 20ms (50Hz) mais ces valeurs peuvent changer d’un servomoteur à l’autre et entre fournisseur. Il vous faudra modifier les valeurs du code pour les adapter à votre servomoteur.
Dans notre cas, nous utilisons le servomoteur MG90S dont les largeurs d’impulsion sont entre 500 et 2500µs sur 20ms.
#!/usr/bin/env python # -*- coding: utf-8 -*- #Libraries import time #https://docs.python.org/fr/3/library/time.html from adafruit_servokit import ServoKit #https://circuitpython.readthedocs.io/projects/servokit/en/latest/ #Constants nbPCAServo=16 #Parameters MIN_IMP =[500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500] MAX_IMP =[2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500] MIN_ANG =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] MAX_ANG =[180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180] #Objects pca=ServoKit(channels=16, address=40) pca = ServoKit(channels=16) # function init def init(): for i in range(nbPCAServo): pca.servo[i].set_pulse_width_range(MIN_IMP[i] , MAX_IMP[i]) # function main def main(): pcaScenario(); # function pcaScenario def pcaScenario(): """Scenario to test servo""" for i in range(nbPCAServo): for j in range(MIN_ANG[i],MAX_ANG[i],1): print("Send angle {} to Servo {}".format(j,i)) pca.servo[i].angle = j time.sleep(0.01) for j in range(MAX_ANG[i],MIN_ANG[i],-1): print("Send angle {} to Servo {}".format(j,i)) pca.servo[i].angle = j time.sleep(0.01) pca.servo[i].angle=None #disable channel time.sleep(0.5) if __name__ == '__main__': init() main()
Applications
- Piloter le robot Quadrina6
Sources
- http://adafruit.github.io/Adafruit-PWM-Servo-Driver-Library/html/class_adafruit___p_w_m_servo_driver.html#aa892432ed08e4b3892c8eb0478168dd8
- https://robojax.com/learn/arduino/robojax-PCA6985.pdf
- https://www.nxp.com/products/power-management/lighting-driver-and-controller-ics/ic-led-controllers/16-channel-12-bit-pwm-fm-plus-ic-bus-led-controller:PCA9685
- https://docs.python.org/fr/3/library/time.html
- https://circuitpython.readthedocs.io/projects/servokit/en/latest/
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie
salut !
D’abord merci pour l’article,
J’ai effectué le même montage pour tester mon module PCA dans le cadre d’un projet de robot,
J’ai malheureusement un problème : la communication i2C semble se faire entre la raspberry pi zero mais … aucun mouvement des moteurs !
Je voulais savoir si vous aviez une piste ? (j’ai déjà vérifier l’ouverture de la communication I2C, la connectique …) mais jusque là rien n’a fonctionné
Encore Merci
Cordialement
Bonjour,
Merci pour le commentaire.
Vous pouvez vérifier l’adresse du module avec un scan I2C (sudo i2cdetect -y 1)
Avez-vous branché une alimentation externe au bornier de puissance pour alimenter les moteurs?
Bonjour,
Merci beaucoup pour votre tuto, il fonctionne parfaitement et il m’a permis de mieux comprendre le principe de fonctionnement !
Bonne continuation
Bonjour, merci beaucoup pour votre commentaire!