Skip to content

Utiliser un servomoteur avec la carte Pi Pico en MicroPython

Intérêt des servomoteurs

Définition

Les servomoteurs, également connus sous le nom de « servo », sont des motorisations électriques qui, via une commande adaptée, permettent d'atteindre et de maintenir une position angulaire spécifique.

Les servomoteurs sont très répandus dans le modélisme (direction des roues des voitures télécommandées, commande des gouvernes de dérive et de profondeur sur les avions, etc), mais aussi dans la robotique et l’industrie.

Les servomoteurs de modélisme ont des vitesses et des couples de maintien plus faibles que leur version industrielle.

Pour exemple, le servo de modélisme SG90 offre une vitesse de 60°/s et un couple de 1,5 kg.cm pour un encombrement très réduit.

La principale différence entre un moteur et un servomoteur est que ce dernier est une motorisation asservie en position pouvant évoluer entre 0 et 180 degrés (voire plus de 300°).

Le SG90 est composé d’un moteur courant continu standard, d’engrenages pour augmenter le couple (et réduire la vitesse), d'un capteur de position angulaire (potentiomètre) ainsi que d’une carte électronique d'asservissement.

Image title

Contrôle d'un servomoteur de modélisme

Signal de commande

Ce servomoteur SG90 est contrôlé à l’aide d’un signal modulé en largeur d’impulsion (PWM) à une fréquence de 50 Hz, ce qui correspond à une impulsion toutes les 20 ms.

Sa position est définie par la durée des impulsions, généralement comprises entre 1 ms et 2 ms.

Image title

La plage de la tension d’alimentation du servo SG90 est de 3.3V à 5V.

Les servomoteurs sont consommateurs en courant, particulièrement quand ils sont soumis à un couple élevé (beaucoup de force exercée sur l’axe de sortie).

Courant consommé

Le 5V de la carte Raspberry Pi Pico est celui de l’USB, généralement limité à 500mA (sur l’ordinateur).

Si l’on veut utiliser un servomoteur consommant plus de 500mA ou plus d'un servomoteurs, il faut alors utiliser une alimentation séparée et veiller à connecter la borne négative de l’alimentation du servomoteur à la broche GND de la carte.

Cablâge du servomoteur SG90 sur la Pi Pico

Schéma de cablâge

Le servomoteur SG90 dispose de 3 fils de connexion :

  • 2 fils pour l’alimentation (masse et alimentation positive) ;
  • 1 pour le signal de commande.

Les couleurs des fils sont différentes afin de les distinguer.

Servomoteur SG90 Couleur du fil RPi Pico
GND Marron GND
5V ou 3.3V Rouge 5V ou 3.3V
Signal PWM Orange GPIO de la Pico

Toutes les broches de sortie de la Pico peuvent être utilisées pour contrôler le servomoteur car elles sont toutes capables de produire une sortie PWM.

Image title

Pilotage du servomoteur depuis la Pico avec un script Python

Pilotage du servomoteur

Il n’est pas indispensable d’utiliser une librairie contrôler le servo c’est uniquement un signal PWM qui indique au servomoteur la position angulaire voulue.

Cependant, le calcul de la durée des impulsions pour atteindre les positions angulaires souhaitées peut s’avérer laborieux quand on veut contrôler plusieurs servomoteurs à la fois. Il est alors pertinent module python.

Script Python basique pour piloter le servo

Sans module Python Servo

Dans le cas du servo SG90, la position minimale correspond à un signal PWM avec une largeur d'impulsion de 0.5ms et la position maximale à 2.4ms.

Il s'agit donc ici de trouver la largeur d’impulsion PWM appropriée pour obtenir la position angulaire désirée.

En effectuant des calculs, on peut déterminer le rapport cyclique du PWM et la valeur numérique (de 0 à 65535) à spécifier dans le script représentative de la largeur d’impulsion.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from machine import Pin,PWM
from time import sleep

sg90 = PWM(Pin(12, mode=Pin.OUT))
sg90.freq(50)

# 0.5ms / 20ms = 0.025
# 2.4ms / 20ms = 0.12

# 0.025 * 65535=1638
# 0.12 * 65535=7864

while True:
    sg90.duty_u16(1638)
    sleep(1)
    sg90.duty_u16(7864)
    sleep(1)

Exercice 6.1

Exécuter le programme précédent.

Script Python utilisant le module servo.py

Je vous invite à utiliser cette bibliothèque MicroPython pour contrôler facilement le servomoteur. Elle s’installe comme les autres bibliothèques MicroPython.

Avertissement

Dans la version 1.19 de MicroPython pour la Raspberry Pi Pico, la librairie servo n’est pas incluse par défaut.

Seule la Pyboard en est dotée d’une par défaut dans MicroPython.

Il faut sauvegarder la librairie sur la Pi Pico directement depuis Thonny IDE sous le nombre servo.py.

Image title

Voici la librairie qu’il faut utiliser :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from machine import Pin, PWM

class Servo:
    __servo_pwm_freq = 50
    __min_u16_duty = 1640 - 2 # offset for correction
    __max_u16_duty = 7864 - 0  # offset for correction
    min_angle = 0
    max_angle = 180
    current_angle = 0.001

    def __init__(self, pin):
        self.__initialise(pin)

    def update_settings(self, servo_pwm_freq, min_u16_duty, max_u16_duty, min_angle, max_angle, pin):
        self.__servo_pwm_freq = servo_pwm_freq
        self.__min_u16_duty = min_u16_duty
        self.__max_u16_duty = max_u16_duty
        self.min_angle = min_angle
        self.max_angle = max_angle
        self.__initialise(pin)

    def move(self, angle):
        angle = round(angle, 2)

        if angle == self.current_angle:
            return

        self.current_angle = angle

        duty_u16 = self.__angle_to_u16_duty(angle)
        self.__motor.duty_u16(duty_u16)

    def __angle_to_u16_duty(self, angle):
        return int((angle - self.min_angle) * self.__angle_conversion_factor) + self.__min_u16_duty

    def __initialise(self, pin):
        self.current_angle = -0.001
        self.__angle_conversion_factor = (self.__max_u16_duty - self.__min_u16_duty) / (self.max_angle - self.min_angle)
        self.__motor = PWM(Pin(pin))
        self.__motor.freq(self.__servo_pwm_freq)

Pour utiliser la librairie, c’est extrême simple :

  • Importez la classe Servo.
  • Définissez un objet Servo qui représente votre servomoteur en spécifiant la broche utilisée pour le piloter.
  • Indiquez la position angulaire souhaitée avec la fonction .move(angle)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from servo import Servo
import time

sg90_servo = Servo(pin=12)  # A changer selon la broche utilisée

while True:
    sg90_servo.move(0)      # tourne le servo à 0°
    time.sleep(1)
    sg90_servo.move(90)     # tourne le servo à 90°
    time.sleep(1)

Exercice 6.2

Exécuter le programme précédent.

Avertissement

Vous devrez peut-être modifier les valeurs de l’offset dans le module servo.py si vous avez un autre type de servomoteur.

1
2
3
4
class Servo:
    __servo_pwm_freq = 50
    __min_u16_duty = 1640 - 2 # offset for correction
    __max_u16_duty = 7864 - 0  # offset for correction