
Servomoteur à commande de position

Présentation
Un servomoteur est un moteur à courant continu capable d'atteindre et de maintenir un angle malgré les contraintes qu'il subit.
Les principales caractéristiques d'un servomoteur sont :
- son couple : c'est-à-dire sa capacité à faire tourner son axe ou à maintenir sa position ;
- sa vitesse de rotation.
Fonctionnement
Branchement
Un servomoteur dispose de trois fils :
- deux fils pour l'alimenter (fil marron ou noir pour la masse et fil rouge pour la phase) ;
- un fil pour le piloter (fil orange ou jaune)

Attention : l'alimentation du moteur par la carte microbi (dont la tension haute est de 3,3 V) peut être insuffisante pour le moteur. Dans ce cas, il faut utiliser une alimentation externe et faire les branchements du schéma ci-dessous :

Pilotage
Le pilotage du servomoteur se fait à l'aide d'une tension modulée (MLI Modulation à Largeur d'Impulsion en français ou PWM Pulse Width Modulation en anglais).
Concrètement, la tension de pilotage est une un signal périodique composé d'impulsions régulières d'une durée réglable.

C'est le rapport de la durée de l'impulsion sur la période du signal qui définit l'angle de l'axe du moteur.
Programmation
Les sorties analogiques de la carte microbit délivrent des signaux modulés.
La méthode set_analog_periode(periode)
disponible pour les sorties analogiques permet de définir la période du signal en ms.
La méthode write_analog(valeur)
permet, quant à elle, de définir l'allure du signal par l'intermédiaire du paramètre valeur
:
- Si
valeur
= 0 alors le rapport (durée impulsion)/(période du signal) = 0 - Si
valeur
= 1023 alors le rapport (durée impulsion)/(période du signal) = 1
Spécifications du servomoteur
Les éléments de la spécification du servomoteur qu'il faut prendre en compte pour le piloter sont :
- la fréquence ou la période du signal à utiliser ;
- la correspondance entre la durée de l'impulsion et l'angle pris par l'axe du moteur ;
- l'angle de rotation maximale de l'axe du moteur.
Exemple : données pour le servomoteur SG90
Fréquence du signal : 50Hz (soit une période de 20 ms)
Angle de rotation maximale du moteur : 180°
Correspondance entre le signal et l'angle :
Durée de l'impulsion | Paramètre valeur de la méthode write_analog(valeur) |
|
Position minimale | environ 1 ms | round(1 / 20 × 1024) = 51 |
Position intermédiaire | 1,5 ms | round(1.5 / 20 × 1024) = 76 |
Position maximale | environ 2 ms | round(2 / 20 × 1024) = 102 |

Remarque : les valeurs minimales et maximales sont à tester.
Exemple de code python
Exemple simple testé sur un servomoteur NG90
from microbit import *
pin0.set_analog_period(20)
for _ in range(5):
pin0.write_analog(31) # valeur testée pour avoir l'angle minimal
sleep(1000)
pin0.write_analog(122) # valeur testée pour avoir l'angle maximal
sleep(1000)
pin0.write_analog(0) # permet d'arréter le moteur
Une classe pour simplifier la programmation
from microbit import *
class ServoMoteur:
"""
Control d'un servomoteur.
Args:
pin (pin0, pin1 ou pin2): pin de connection.
freq (int): fréquence du signal en Hz.
min_us (int): durée minimale du cycle actif (en µs).
max_us (int): durée maximale du cycle actif (en µs).
angle (int): plage de l'angle de rotation du servomoteur (en degrés).
"""
def __init__(self, pin, freq=50, min_us=700, max_us=2300, plage_degrees=180):
self.min_us = min_us
self.max_us = max_us
self.us = 0
self.freq = freq
self.plage_degrees = plage_degrees
self.periode = round((1/self.freq) * 1000) # hertz to miliseconds
self.pin = pin
self.pin.set_analog_period(self.periode)
def write_us(self, us):
us = min(self.max_us, max(self.min_us, us))
duty = round(us * 1024 * self.freq / 1000000)
self.pin.write_analog(duty)
def write_angle(self,angle):
total_range = self.max_us - self.min_us
us = self.min_us + total_range * angle // self.plage_degrees
self.write_us(us)
def off(self):
self.pin.write_digital(0) # turn the pin off
# Utilisation de la classe
moteur = ServoMoteur(pin0)
while True:
test_a = button_a.is_pressed()
test_b = button_b.is_pressed()
if test_a or test_b:
if test_a:
display.show('A')
moteur.write_angle(0)
else:
display.show('B')
moteur.write_angle(180)
else:
display.clear()
moteur.off()
sleep(50)