🛠 Piloter un micro-servo avec le PWM
Objectifs
Générer un signal PWM de servo avec le RP2040 : la puce dispose de 16 canaux PWM (8 tranches × 2 canaux). Un micro-servo standard (SG90, MG90S…) attend une fréquence de 50 Hz et une impulsion de 1 ms pour le centre (0,5 ms ≈ -90°, 2,5 ms ≈ +90°). Tu vas configurer une tranche PWM en mode « correct phase » avec le Pico SDK et balailler l'angle en douceur.
Matériel
- 1 × Raspberry Pi Pico
- 1 × micro-servo (SG90 ou MG90S)
- Alimentation externe 4,8-6 V pour le servo (ne pas l'alimenter depuis le 3V3 de la Pico : l'appel de courant au démarrage dépasse ce que la carte fournit confortablement)
- Câbles : signal (orange/jaune) sur GP1, moins servo sur GND Pico ET sur le moins de l'alimentation (masse commune obligatoire !)
Code complet
// servo.c — GP1, 50 Hz, pulse 0,5..2,5 ms (mode phase-correct)
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#define SERVO_PIN 1
#define PERIOD_US 20000u // 50 Hz
static uint16_t angle_to_pulse_us(int angle) { // 0..180 -> 500..2500 us
return 500 + (uint16_t)(angle * 2000 / 180);
}
int main(void) {
gpio_set_function(SERVO_PIN, GPIO_FUNC_PWM);
uint slice = pwm_gpio_to_slice_num(SERVO_PIN);
pwm_set_clkdiv_mode(slice, PWM_DIV_FREE_RUNNING);
pwm_set_clkdiv(slice, 125.0f); // 125 MHz / 125 = 1 MHz (1 us/tick)
pwm_set_wrap(slice, PERIOD_US - 1);
pwm_set_enabled(slice, true);
while (true) {
for (int a = 0; a <= 180; a += 5) {
pwm_set_gpio_level(SERVO_PIN, angle_to_pulse_us(a));
sleep_ms(20);
}
for (int a = 180; a >= 0; a -= 5) {
pwm_set_gpio_level(SERVO_PIN, angle_to_pulse_us(a));
sleep_ms(20);
}
}
}
Vérification attendue
Le servo balaie lentement de 0° à 180° puis revient, sans à-coups. En débranchant le signal, le servo doit rester immobile (aucune impulsion = pas de couple). Vérifie aussi que le 3,3 V de la carte ne « plonge » pas quand le servo force : symptôme = Pico qui redémarre, donc masse/alimentation servo à revoir.
Erreurs fréquentes
- Oubli de la masse commune entre Pico et alimentation servo : le servo jitter frénétiquement.
- Servo alimenté depuis le 3V3 de la Pico : brown-out et reboots.
- Mauvaise horloge de tranche : sans le
clkdivadapté, la période est fausse et le servo ne réagit pas — rappelle-toi que le PWM vient du clock 125 MHz. - Confondre niveau (
level) et période : le niveau doit rester inférieur au wrap, sinon la sortie reste bloquée à 1. - Alimenter le servo en 5 V sur la broche de signal : le PWM de commande doit rester en 3,3 V, la Pico n'est pas 5 V-tolérante.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython