Deux choix s'offre à nous :

  • premièrement, l'utilisation du MicroPython, choix privilégié par la fondation Raspberry,
  • deuxièmement, l'utilisation du CircuitPython, fork de la société Adafruit.

Dans ce premier tuto, nous utiliserons MicroPython.

Montage Lego

Nous utiliserons le mécanisme du précédent tuto avec l'Arduino. Mais avant de se lancer dans ce projet, nous allons voir les deux solutions que j'ai réalisé sur le montage Lego précédent. En fonction de la position zéro degré du servo, il faudra utiliser soit le bras composé de deux Axle and Pin Connector Angled (ref 32013) et d'un Axle 2L Notched (ref 32062), soit le montage par un Liftarm Thick 1 x 3 (ref 32523).

montage 1 - deux Axle and Pin Connector Angled

mecanisme v2

montage 2 - Liftarm Thick 1 x 3

Installation du système MicroPython

Lors de l'achat d'un Pi Pico, celui-ci est vendu sans système d'exploitation. Pour installer MicroPython, brancher le Pi Pico sur un port USB de votre ordinateur et appuyer en même temps sur le bouton BOOTSEL. Normalement une fenêtre s'affiche comme ci-dessous.

bootsel

Lancez le programme Thonny et cliquez sur le menu en bas à droite

menu python01

Choisissez Install MicroPython

menu python02

 Une boîte de dialogue s'affiche et choisissez le modèle de Pi Pico. Dans notre exemple, nous prenons le Pi Pico sans Wifi : le Raspberry Pi * Pico/Pico H version 1.21.0

choix PI Pico

Une fois le système, cliquez sur Close.

Install done

Pour vérifier le bon fonctionnement du Pi Pico, cliquez sur le bouton rouge qui va redémarrer le système.

Reboot thonny

En bas de la fenêtre console, vous devriez voir ce message :

MicroPython v1.21.0 on 2023-10-06; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>>

Branchement du servomoteur

Le branchement du servo est très simple. Le servo comporte trois fils :

  • le fil marron correspond à la masse GND
  • le fil rouge correspond au +5V
  • le fil orange correspond au signal de commande.

Dans notre exemple, nous utiliserons le GP28, broche 34.

cablage servo pico tuto

premier test

Il est possible de commander le servo sans une librairie spécialisée mais l'utilisation du servo ne sera pas simple.

Info
Le servomoteur GeekServo permet une rotation de 0° à 270°. Il faudra modifier en conséquence la librairie servo.py en initialisant la variable max_angle à 270.

max_angle = 270

Nous avons besoin de contrôler l'angle de rotation du servo, nous utiliserons la librairie ci-dessous (le basckslash dans le code permet le retour à la ligne) :

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):<a href="#" class="alert-link">an example link</a>
        # 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)

Sauvegardez la librairie dans le Pi Pico en nommant le fichier servo.py. Utilisez pour cela le logiciel Thonny.

 librairie servo

Maintenant, nous pouvons passer au programme. Importons la classe Servo.

from servo import Servo

Initialisation de l'objet my_servo en l'attachant au GP28

my_servo = Servo(pin=28)

Avant de réaliser un programme, il sera judicieux de vérifier les angles de départ et de fin avec un des deux types de montage. Pour cela, il suffit d'ajouter la commande suivante. Pour ma part, j'ai choisi le montage 1 avec un angle de départ à 9° et de fin à 45°.

my_servo.move(10)

Il suffit de lancer le programme avec le bouton vert (Run current script) pour obtenir l'angle désiré du servomoteur.

Premier programme

Le but du programme sera de simuler un combat médiéval. Le combat sera déclenché par l'appui d'un bouton. Voici le cablage.

cablage servo button tuto

 Maintenant, voyons le code.

import machine
from servo import Servo
my_servo = Servo(pin=28)

button = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_DOWN)

while True:
    if button.value() == 1:
        my_servo.move(45)
    else:
        my_servo.move(9)

Quand on appuie sur le bouton, le servo se déplacera à la position finale. Quand on relache le bouton, le servo reprend la position de départ. Pour le rendre permanent à chaque mise en route du Pi Pico, sauvegardez le programme dans le Pi Pico en le nommant main.py.

sauve main 

Petite démo

Création d'un petit scénario

Maintenant, nous allons créer un petit scénario. L'appui sur le bouton va permettre le combat pendant 10 mouvements avec une boucle for. Nous utiliserons un petit timer pour décomposer le mouvement. Voici le code :

import machine #importe la librairie du Pi Pico
import utime   #importe la librairie mesurant le temps
from servo import Servo #importe la librairie gérant les servomoteurs

#initialisation de l'objet my_servo en l'attachant au GP28
my_servo = Servo(pin=28)

#initialisation de l'objet button en l'attachant au GP16
button = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_DOWN)

#boucle principale
while True:
    if button.value() == 1:
        # si le bouton est appuyé on lance une boucle (10 fois)
        for i in range(10):
            #déplacement du servomoteur vers la droite 45°
            my_servo.move(45)
            #délai d'une demi-seconde
            utime.sleep(0.5)
            #déplacement du servomoteur vers la gauche 9°
            my_servo.move(9)
            #délai d'une demi-seconde
            utime.sleep(0.5)

 et voici une petite démo

Comme vous avez pu le constater, j'utilise un shield grove pour Pi Pico. Celui-ci fera l'objet d'un prochain tuto.