Créditos: Paula Campbell
Fecha: 09/07/25
Visualizaciones: 42

PWM, encoders y servos: todo lo que tenés que saber para mover con precisión
Arduino
¿Te preguntaste alguna vez cómo hace un brazo robótico para moverse justo hasta cierta posición y quedarse ahí sin pasarse? ¿O cómo un auto a control remoto gira las ruedas con precisión? Detrás de todo eso suele estar un servomotor: un pequeño pero poderoso motor que se mueve justo hasta donde le decís… ni más, ni menos. Y para saber qué tan lejos se movió, muchos servos usan un sensor llamado encoder.
¿Qué es un encoder?
Un encoder es un dispositivo que hace la acción opuesta del motor: convierte movimientos en una señal eléctrica. En otras palabras, similar al potenciómetro, el encoder se encarga de sensar la posición o la rotación de un eje de giro. ¿Cómo lo hace? Generalmente están compuestos por un led, un disco con ranuras y un fotodiodo. Al girar el disco que se encuentra entre el led y el fotodiodo, el fotodiodo recibe pulsos de luz del led y genera una señal eléctrica que al ser procesada provee información de la posición o la rotación del disco. Por ejemplo, la ruedita del mouse tiene un encoder, ya que al girarla, el mouse puede saber en qué posición está o cuántos grados giró.
Hay dos tipos de encoders:
- Incrementales o Rotativos: indican cuánto giró el eje
- Absolutos: indican la posición exacta del eje, gracias a un patrón único de ranuras en cada ángulo
¿Qué es un servomotor?
Un servomotor es un tipo de motor especial que se diferencia de otros motores porque es capaz de moverse una cierta cantidad de grados y mantenerse fijo en esa posición, no gira libremente. Dentro de un servomotor hay un motor, un circuito que controla el movimiento del motor y un encoder, en donde el encoder se retroalimenta el circuito con la posición del eje. El circuito se encarga de que el motor llegué a la posición deseada y se quede fija ahí, lo frena en el momento justo: a medida que el motor gira, el encoder le envía la señal de la posición al circuito de control, y con esa información el circuito de control decidirá si frenar o no el motor.
Los servos son muy útiles para muchas aplicaciones, por ejemplo, son usados en autos a control remoto, robótica, impresoras 3D, CNCs, proyectos de Arduino.
¿Cómo controlar un servo con Arduino?
Los servos estándares contienen potenciómetros en vez de encoders para leer la posición del motor y se desplazan a su velocidad máxima hasta alcanzar la posición designada.
La señal que se le debe entregar para cambiar su posición es una señal de PWM en donde el tiempo en alto debe ser equivalente al ángulo al que se quiere llegar.
Una señal PWM (del inglés, “Modulación por Ancho de Pulso”) es una forma de simular una señal analógica usando pulsos digitales, es una señal que solamente puede adoptar dos valores: encendido y apagado. La frecuencia en una señal PWM se mantiene constante, pero lo que varía es cuánto tiempo en “alto” (en su valor máximo) y en “bajo” (su valor mínimo) tiene la señal. Si la mitad del tiempo del ciclo la señal está en alto y la otra mitad está en bajo, la señal tendrá un ciclo de trabajo del 50%, es decir, su valor promedio es la mitad del valor máximo.
El truco para controlar a un servo con una señal PWM está en el ancho del pulso de la señal.
Tiempo en alto de la señal PWM | Ángulo |
1 ms | 0° |
1.5 ms | 90° |
2 ms | 180° |
Esto quiere decir que si el tiempo del pulso en alto es inferior a 1.5 ms, el servo se moverá en sentido contrario a las agujas del reloj, hacia la posición de los 0°; si el tiempo del pulso en alto es superior a 1.5 ms, el servo se moverá en sentido de las agujas del reloj, hacia la posición de los 180°; y si el tiempo del pulso en alto es 1,5 ms, el servo se moverá hacia la posición de los 90°. Estos pulsos se repiten cada 20 ms (frecuencia: 50 Hz).
Conexiones
El servomotor cuenta con tres cables: dos de alimentación (a 5V y GND) y uno de señal de datos.
- Cable negro o marrón (tierra) → GND
- Cable rojo (VCC) →5V
- Cable amarillo o naranja (señal) →9
Código con librería “Servo.h”
#include
Servo servo;
void setup() {
servo.attach(9); // conecta el servo al pin 9
}
void loop() {
servo.write(0); // mueve a 0 grados
delay(2000); // espera 2 segundos
servo.write(180); // mueve a 180 grados
delay(2000); // espera 2 segundos
}
Código sin librería “Servo.h”
En proyectos a escala es conveniente usar la librería, pero para entender en profundidad el funcionamiento del servo y la señal con la que se controla, puede ser de gran ayuda escribir el código desde cero. En este código, en vez de usar la librería, creamos una función que genera una señal PWM con las funciones digitalWrite() y delayMicroseconds(). Utilizamos la función map() para generar el ancho de pulso entre 500 y 2500 ms (agrandamos el rango para asegurarnos que funcione en todos los servos). Finalmente, usamos un bucle para repetir el pulso PWM por un segundo.
const int pinServo = 9;
void setup() {
pinMode(pinServo, OUTPUT);
}
void loop() {
moverServo(0); // mueve a 0°
delay(2000);
moverServo(180); // mueve a 180°
delay(2000);
}
// Función que genera un pulso PWM de 50Hz
void moverServo(int angulo) {
// Convertimos el ángulo (0° a 180°) en tiempo de pulso (en microsegundos)
int pulso = map(angulo, 0, 180, 500, 2500); // ancho entre 0.5ms y 2.5ms
// Usamos un bucle para enviar 50 pulsos (aproximadamente 1 segundo de señal), que permite que el servo tenga tiempo de moverse a la posición deseada.
for (int i = 0; i < 50; i++) {
digitalWrite(pinServo, HIGH);
delayMicroseconds(pulso);
digitalWrite(pinServo, LOW);
delayMicroseconds(20000 - pulso); // completamos los 20ms (frecuencia = 50Hz)
}
}
Conclusión
Los servomotores son la clave para lograr movimientos precisos y controlados. Gracias a su sistema de retroalimentación (encoder o potenciómetro) y su fácil manejo con PWM, son ideales para todo tipo de proyectos electrónicos, desde los más simples hasta los más profesionales.
Archivos de la noticia:
