🛠 Piloter un micro-servo avec le PWM
Objetivos
Configurar un slice PWM del RP2350 (16 canales PWM, 8 slices dobles) a 50 Hz con una resolución suficiente para generar impulsos de 1 a 2 ms, y controlar un micro-servo en barrido de ángulo. Diferencia con el RP2040: mismos principios PWM, pero el RP2350 permite divisiones de reloj más finas a 150 MHz.
Material
- 1 × Raspberry Pi Pico 2
- 1 × micro-servo (SG90/MG90S)
- Se recomienda alimentación externa para más de 2 servos; 1 servo admitido desde 5 V USB con masas comunes
- Pin: GP2 (salida PWM slice 1A, confirmado por los ejemplos oficiales de Pico 2)
Código completo
/* 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);
}
}
Verificación esperada
El servo barre regularmente de 0° a 180° y vuelve, en bucle. En el osciloscopio: periodo de 20 ms (50 Hz), ancho de pulso variando de aproximadamente 1 ms a 2 ms. Ajuste los límites level según su servo.
Errores frecuentes
- Divisor de reloj incorrecto: con wrap 19999, un clkdiv de 125 da 50 Hz; un clkdiv olvidado produce una señal en kHz que hace zumbar y calentar el servo.
- Alimentar varios servos desde el 3V3 de la placa: el límite es ~300 mA en el pin 3V3; utilizar un 5 V externo y conectar las masas.
- Superar los topes mecánicos: limitar a 0–180° (algunos servos estándar 170°) para evitar que se bloqueen.
- Olvidar
pwm_set_enabled: el contador funciona pero la salida permanece inactiva.
Otros tutoriales para esta placa
Ejemplos de código para esta placa
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython