Étiquettes : , ,

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
  • RapsberryPi3B+
  • PCA9685Module

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.

Code

La carte Raspberry Pi est un micro ordinateur. Il peut donc être programmé dans tous les langages. Les plus utilisés sont le Bash et le Python.
Pour utiliser le module PCA9685 nous utilisons la librairie adafruit_servokit.h. 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 400 et 2400µs sur 20ms.
Pour définir la commande PWM, la librairie présente deux fonctions setPWM() et writeMicroseconds(). La fonction writeMicroseconds() nous permet d’utiliser les valeurs constructeur directement. Pour la fonction setPWM, il nous faut trouver la largeur d’impulsion correspondante sur 4096 (2^12, 12bits).

#!/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)

# 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