🛠 Piloter un micro-servo avec le PWM
Objectifs
Configurer un slice PWM du RP2350 (16 canaux PWM, 8 slices doubles) en 50 Hz avec une résolution suffisante pour générer des impulsions de 1 à 2 ms, et piloter un micro-servo en balayage d'angle. Différence avec le RP2040 : mêmes principes PWM, mais le RP2350 permet des divisions d'horloge plus fines à 150 MHz.
Matériel
- 1 × Raspberry Pi Pico 2
- 1 × micro-servo (SG90/MG90S)
- Alimentation externe conseillée pour plus de 2 servos ; 1 servo supporté depuis 5 V USB avec masses communes
- Broche : GP2 (sortie PWM slice 1A, confirmée par les exemples officiels Pico 2)
Code complet
/* servo.c — balayage 0..180 deg sur GP2, PWM 50 Hz */
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#define SERVO_PIN 2
#define WRAP 19999 /* 125 MHz / (125 * 20000) = 50 Hz */
static void servo_angle(float deg) {
/* 0 deg -> 1 ms, 180 deg -> 2 ms ; 1 pas = 10 ns avec clkdiv 125 */
uint32_t level = 100 + (uint32_t)(deg * 5.0f); /* 100..1000 */
pwm_set_chan_level(pwm_gpio_to_slice_num(SERVO_PIN), PWM_CHAN_A, level);
}
int main(void) {
gpio_set_function(SERVO_PIN, GPIO_FUNC_PWM);
uint slice = pwm_gpio_to_slice_num(SERVO_PIN);
pwm_set_clkdiv(slice, 125.0f); /* 1 pas = 1 us / 100 ? voir texte */
pwm_set_wrap(slice, WRAP);
pwm_set_enabled(slice, true);
for (float a = 0; ; a += 5) { /* triangle 0->180->0 */
float ang = (a <= 180.0f) ? a : 360.0f - a;
servo_angle(ang);
if (a >= 355.0f) a = 0;
sleep_ms(20);
}
}
Vérification attendue
Le servo balaie régulièrement de 0° à 180° et revient, en boucle. À l'oscilloscope : période 20 ms (50 Hz), largeur d'impulsion variant d'environ 1 ms à 2 ms. Ajustez les bornes level selon votre servo.
Erreurs fréquentes
- Mauvais diviseur d'horloge : avec wrap 19999, un clkdiv de 125 donne 50 Hz ; un clkdiv oublié produit un signal en kHz qui fait grésiller et chauffer le servo.
- Alimenter plusieurs servos depuis le 3V3 de la carte : la limite est ~300 mA sur la broche 3V3 ; utiliser un 5 V externe et relier les masses.
- Dépassement des butées mécaniques : limiter à 0–180° (certains servos standards 170°) pour ne pas les faire caler.
- Oublier
pwm_set_enabled: le compteur tourne mais la sortie reste inactive.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython