Ignorer et passer au contenu

Livraison offerte à partir de 50€ d'achats, livrée sous 48h !

Livraison à partir de seulement 2.50€ !

Contents Menu Expand Light mode Dark mode Auto light/dark mode

Utiliser un servomoteur avec une carte Pi Pico en MicroPython

(Mis à jour le 05/01/2023)

Les servomoteurs, également connus sous le nom de « servo », sont une forme spéciale de moteurs qui peuvent être commandés et maintenir une position angulaire spécifique avec précision. Ils ont un excellent rapport poids puissance. Le servo bleu SG90 de TowerPro, par exemple, offre un couple de 1,5 kg/cm à seulement 9g. Grâce à son faible prix et à sa mise en œuvre facile avec une Pi Pico, il est un choix parfait pour les makers !

Note

Les servos 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, comme pour réguler des flux de liquides dans des vannes par exemple.

Prendre en main le fameux servomoteur SG90

La principale différence entre un moteur classique et un servomoteur est que la plupart des servomoteurs peuvent seulement pivoter entre 0 et 180 degrés. Un servomoteur est composé d’un moteur courant continu (CC) standard, d’engrenages pour augmenter le couple (et réduire la vitesse) ainsi que d’un système de régulation. Ce qui est remarquable est que tous ces mécanismes sont intégrés dans un boîtier si petit !

Avertissement

Il est recommandé d’éviter de manipuler manuellement l’axe du servomoteur et de s’arrêter avant la butée, car elle est assez fragile (en plastique).

Fonctionnement d’un servomoteur basique

Schéma interne servomoteur

Un petit moteur à courant continu est lié à un potentiomètre avec un circuit électronique, ce qui permet de réguler la vitesse du moteur en fonction de la position du potentiomètre. Des engrenages sont connectés à l’axe de sortie du moteur pour augmenter le couple et réduire la vitesse de rotation. Lorsque le moteur fonctionne, les engrenages vont faire bouger l’axe principal qui contient le potentiomètre. Si le mouvement s’arrête, le circuit électronique ajuste automatiquement la vitesse du moteur afin de maintenir le bras et le potentiomètre à la même position. Cette caractéristique est utile pour les bras des robots qui ne s’abaissent pas sous leur propre poids lorsque le mouvement s’arrête.

relation largeur impulsion et angle de rotation servo

Ce servomoteur bleu 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.

Comment alimenter le servomoteur avec un Raspberry Pi Pico

La tension d’alimentation optimale de ce servo SG90, selon la fiche technique , est de 5V, mais il semble également fonctionner à 3.3V.

Note

Avec une tension de 5V, le moteur sera plus réactif et la rotation sera beaucoup plus rapide.

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). 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 plus de deux 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.

Branchements du servomoteur SG90 sur la Pi Pico

Le servomoteur SG90 contient 3 fils, 2 pour l’alimentation et 1 pour le signal de commande. Les couleurs des fils sont différentes afin de les distinguer.

Correspondance des broches

Servomoteur SG90

Couleur du fil

RPi Pico

GND

Marron

GND

5V

Rouge

5V ou 3V3

Signal PWM

Orange

GP12

Note

Chez certains modèles, le fil pour le signal est jaune ou blanc et non pas orange.

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.

Circuit pour piloter un servomoteur avec une Raspberry Pi Pico

Voici le circuit minimaliste pour utiliser un servomoteur. Il y a une version avec la Pi Pico et une version avec la carte uPesy RP2040 DevKit, une Pi Pico améliorée.

Câblage servo SG90 rpi pi pico micro python
Câblage servo SG90 rpi pi pico micro python

Voici un exemple sur breadboard avec la carte uPesy RP2040 DevKit, où le servo est alimenté en 3.3V.

Câblage du servo SG90 et RP2040 sur plaque de prototypage

Piloter un servomoteur depuis la Pico avec un script Python

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 des bonnes valeurs peut s’avérer laborieux quand on veut contrôler plusieurs servomoteurs à la fois. Par conséquent, je suggère d’utiliser une librairie déjà en place pour vous faire gagner du temps dans vos projets DIY à venir.

En fait, puisque c’est la largeur d’impulsion du signal PWM qui indique au servomoteur la position angulaire voulue, il n’y a pas vraiment besoin de librairie pour maîtriser la bête 😎. Mais cela peut venir rapidement fastidieux de calculer les bonnes valeurs, surtout quand on veut en piloter plusieurs en même temps. C’est pour cela que je recommanderai d’utiliser plutôt une librairie toute faite pour vous simplifier la vie dans nos projets DIY futurs.

Script Python basique pour piloter le servo avec ses propres calculs

Dans le cas du servo SG90 de TowerPro, la position minimale correspond à un signal PWM avec une largeur de 0.5ms et la position maximale à 2.4ms. En effectuant des calculs, on peut déterminer le duty-cycle du PWM et la valeur en bits de la largeur d’impulsion à mettre dans le script.

Note

Le défi est de trouver la largeur d’impulsion PWM appropriée pour obtenir la position angulaire désirée.

Je ne vais pas détailler les calculs, car on va plutôt utiliser une libraire toute faite pour la suite. Voici un script de base à ce sujet :

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.5% duty cycle
# 2.4ms/20ms = 0.12 = 12% duty cycle

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

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

Piloter un servo via un script Python avec la librairie 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.

installer librairie dans thonny ide

On peut sauvegarder la librairie sur la Pi Pico directement depuis Thonny IDE

Voici la librairie qu’il faut utiliser:

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):
        # round to 2 decimal places, so we have a chance of reducing unwanted servo adjustments
        angle = round(angle, 2)
        # do we need to move?
        if angle == self.current_angle:
            return
        self.current_angle = angle
        # calculate the new duty cycle and move the motor
        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 bleu en spécifiant la broche utilisée pour le piloter.

  • Indiquez la position angulaire souhaitée avec la fonction .move(angle)

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)

Avertissement

Vous devrez peut-être modifier les valeurs de l’offset si vous avez un autre type de servomoteur :

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

Voici une vidéo de démonstration avec le code ci-dessus :

Contrôle du servo SG90 avec RP2040

Contrôle du servo SG90 avec la carte uPesy RP2040 DevKit