Control de servomotores con ESP32 de manera sencilla
Los motores servo son componentes versátiles y esenciales en una amplia variedad de proyectos de robótica y electrónica. Originalmente utilizados en vehículos a control remoto, estos motores han encontrado aplicaciones en áreas tan diversas como la automatización del hogar, modelos de avión, y dispositivos mecánicos que requieren un control preciso. La capacidad de posicionamiento exacto que ofrecen los servos los convierte en herramientas ideales para cualquier aficionado o profesional de la electrónica.
En este tutorial, aprenderás a controlar un motor servo utilizando un ESP32, una poderosa placa de desarrollo que combina conectividad Wi-Fi y Bluetooth. Comenzaremos con el movimiento de un servo en un barrido automático, luego introduciremos un potenciómetro para controlar manualmente la posición del servo, y finalmente, expandiremos el proyecto para manejar múltiples servos. Empezaremos revisando algunos conceptos básicos sobre los motores servo. Si ya estás familiarizado con estos conceptos, puedes saltar a la sección de conexión del hardware.
- Conceptos básicos sobre los motores servo
- Conexión del motor servo al ESP32
- Configuración del entorno de programación Arduino IDE
- Instalación de la biblioteca
- Ejemplo 1: Haciendo un barrido con el servo
- Ejemplo 2: Controlando el servo con un potenciómetro
- Ejemplo 3: Controlando múltiples servos
- Avanzando más allá
Conceptos básicos sobre los motores servo
Un motor servo típico está compuesto por cinco componentes principales que trabajan en conjunto:
- Motor de corriente continua (DC): Este es el componente central que proporciona la fuerza rotacional. A diferencia de los motores convencionales, su control permite un movimiento preciso.
- Transmisión (Gearbox): La transmisión aumenta el torque del motor y mejora la precisión al reducir la velocidad del motor, lo que resulta en un movimiento más controlado.
- Palanca del servo (Servo Horn): Esta es la parte que se conecta al eje de salida y permite acoplar el objeto que se desea mover, como un brazo robótico o un timón.
- Potenciómetro: Funciona como un sensor de posición variable. A medida que gira el eje de salida, el potenciómetro cambia su resistencia, proporcionando información sobre la posición actual al controlador.
- Unidad de control: Este es el "cerebro" del servo. Recibe señales del controlador externo (como el ESP32), verifica la posición del potenciómetro y controla el motor DC.
Cómo funcionan estos componentes juntos
El motor servo opera mediante un sistema de retroalimentación en lazo cerrado. Cuando se envía una señal para mover el servo a una posición específica, la unidad de control recibe la instrucción.
El potenciómetro, conectado al eje de salida, siempre conoce la posición del servo. Cuando el motor gira, el eje de salida rota y el potenciómetro cambia su resistencia, generando un voltaje que indica la posición actual. Este voltaje se utiliza como retroalimentación para el controlador.
La unidad de control compara continuamente el voltaje de retroalimentación con la señal de posición deseada. Si hay una diferencia, la unidad ajusta la potencia y la dirección del motor DC para corregir esta discrepancia. Este proceso se repite rápidamente, permitiendo que el servo mantenga su posición incluso ante fuerzas externas.
Este sistema se conoce como servomecanismo o simplemente servo, y permite un control preciso de la velocidad y dirección del motor.
Funcionamiento de los motores servo
Los motores servo se controlan mediante una técnica llamada Modulación por Ancho de Pulsos (PWM). PWM consiste en enviar una serie de pulsos eléctricos al servo a intervalos regulares, generalmente 50 veces por segundo (50 Hz).
Lo crítico para controlar la posición del servo no es la frecuencia de los pulsos, sino la duración de cada pulso, conocida como ancho de pulso.
- Un pulso corto de aproximadamente 1 ms indica al servo que se mueva a 0 grados.
- Un pulso de alrededor de 1.5 ms posiciona el servo a 90 grados.
- Un pulso más largo de aproximadamente 2 ms mueve el servo a 180 grados.
- Para posiciones intermedias, se utilizan pulsos que caen entre estos valores.
Esto permite un control preciso sobre la dirección en la que apunta el servo, ya que la unidad de control mide la duración de los pulsos y ajusta el motor en consecuencia.
Conexiones del motor servo
La mayoría de los servos de hobby tienen un conector estándar de tres pines. Aunque la codificación de colores puede variar, generalmente los pines están dispuestos en el mismo orden:
- GND: Pin de tierra.
- 5V: Suministra energía al motor servo. La mayoría de los servos requieren entre 4.8V y 6V.
- Control: Recibe la señal PWM del microcontrolador, que determina la posición del servo.
Conexión del motor servo al ESP32
Para este proyecto, utilizaremos un SG90 Micro Servo Motor, que funciona con 5V y puede rotar hasta 180 grados.
Es importante tener en cuenta que cuando el servo está inactivo, solo necesita aproximadamente 10mA de corriente. Sin embargo, al moverse, puede necesitar entre 100mA y 250mA. Para la mayoría de los proyectos simples, es posible alimentarlo directamente desde el pin VIN del ESP32, pero si se requiere más de 250mA, es recomendable usar una fuente de alimentación externa.
Para conectar el motor SG90 al ESP32, sigue estos pasos:
- Conecta el cable rojo al pin VIN del ESP32.
- Conecta el cable negro o marrón al pin GND.
- Conecta el cable naranja o amarillo al GPIO13 del ESP32. Puedes usar cualquier GPIO del ESP32, pero se recomienda evitar los GPIOs 9, 10 y 11, ya que están conectados al SPI integrado.
Consulta la siguiente tabla para las conexiones del pin:
Pin | Conexión |
---|---|
GND | Tierra |
5V | Alimentación |
Control | GPIO13 |
Configuración del entorno de programación Arduino IDE
Usaremos Arduino IDE para programar el ESP32, así que asegúrate de tener instalado el complemento de ESP32 antes de continuar.
Instalación de la biblioteca
Arduino IDE incluye una biblioteca Servo para controlar motores servo, pero no es compatible con el ESP32. Sin embargo, hay varias bibliotecas disponibles específicamente para el ESP32 que emulan la biblioteca de Arduino Servo y añaden funcionalidades adicionales.
Para este tutorial, utilizaremos la biblioteca ESP32Servo de Kevin Harrington. Esta biblioteca no solo replica las funciones de la biblioteca original de Arduino, sino que también introduce capacidades adicionales.
Para instalar la biblioteca:
- Abre tu programa Arduino IDE y haz clic en el icono del Gestor de Bibliotecas.
- Escribe “ESP32Servo” en la barra de búsqueda.
- Busca la biblioteca “ESP32Servo” creada por Kevin Harrington.
- Haz clic en el botón Instalar.
Ejemplo 1: Haciendo un barrido con el servo
El primer ejemplo consiste en hacer que el eje de un motor servo se mueva de un lado a otro a través de 180 grados. Carga el siguiente código en tu ESP32:
#include
Servo myservo;
int pos = 0;
int servoPin = 13;
void setup() {
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
myservo.setPeriodHertz(50);
myservo.attach(servoPin, 500, 2400);
}
void loop() {
for (pos = 0; pos = 0; pos -= 1) {
myservo.write(pos);
delay(15);
}
}
Una vez que subas el código a tu ESP32 y conectes el hardware, deberías observar que el servo se mueve en un movimiento de barrido. Ten en cuenta que puede que no logre un barrido completo de 180 grados debido a variaciones entre motores servos. Puedes ajustar el rango de barrido modificando los valores de tiempo en el código. Para un SG90 servo, los valores de 500 y 2400 son generalmente más adecuados.
Explicación del código: barrido de servo
El código comienza incluyendo la biblioteca ESP32Servo. Luego, se crea un objeto llamado myservo
que representa el motor servo que se controlará. Además, se definen dos variables: una para la posición actual del servo y otra para especificar el pin GPIO al que está conectado el cable de señal del servo.
int pos = 0;
int servoPin = 13;
En la función setup, verás líneas relacionadas con la asignación de temporizadores, lo cual es necesario al usar la biblioteca ESP32Servo.
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
La frecuencia de la señal PWM se establece en 50 Hz, que es la frecuencia estándar para la mayoría de los servos de hobby.
myservo.setPeriodHertz(50);
Luego, el método myservo.attach()
vincula el objeto servo al pin GPIO real en el ESP32. Este método también establece los anchos de pulso mínimo y máximo que determinan el rango de movimiento del servo. En este caso, se utilizan 500 microsegundos para 0 grados y 2400 microsegundos para 180 grados.
myservo.attach(servoPin, 500, 2400);
La función loop contiene dos bucles for
. El primer bucle mueve el servo de 0 a 180 grados, mientras que el segundo lo mueve de regreso a 0 grados. En cada iteración, se actualiza la posición del servo y se espera 15 milisegundos para que el servo alcance la posición especificada.
for (pos = 0; pos <= 180; pos += 1) {
myservo.write(pos);
delay(15);
}
Ejemplo 2: Controlando el servo con un potenciómetro
En este segundo ejemplo, añadiremos un potenciómetro para ajustar manualmente la posición del servo. Este proyecto es muy útil para controlar la inclinación y giro de un sensor conectado al servo.
Conexiones del circuito
Reutilizaremos la conexión del ejemplo anterior, pero esta vez añadiremos un potenciómetro de 10KΩ. Conecta un extremo del potenciómetro a tierra, el otro a VIN, y el terminal del medio a GPIO34.
Código Arduino
El código para hacer que el servo siga la posición del potenciómetro es más sencillo que el del barrido.
#include
Servo myservo;
int servoPin = 13;
int potPin = 34;
int val;
void setup() {
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
myservo.setPeriodHertz(50);
myservo.attach(servoPin, 500, 2400);
}
void loop() {
val = analogRead(potPin);
val = map(val, 0, 4096, 0, 180);
myservo.write(val);
delay(200);
}
Explicación del código
En este ejemplo, se han introducido dos nuevas variables: una para especificar el pin GPIO al que está conectado el potenciómetro y otra para almacenar el valor leído del pin analógico.
int potPin = 34;
int val;
Comenzamos la función loop leyendo el valor del potenciómetro.
val = analogRead(potPin);
La función analogRead()
devuelve un valor entre 0 y 4096. Sin embargo, dado que el servo solo puede rotar 180 grados, debemos escalar este valor.
Utilizamos la función map()
para remapear el número de un rango a otro. Esta línea convierte la lectura a grados entre 0 y 180.
val = map(val, 0, 4096, 0, 180);
Finalmente, usamos el comando write()
para actualizar la posición del servo de acuerdo con el valor seleccionado por el potenciómetro.
Ejemplo 3: Controlando múltiples servos
El ESP32 cuenta con 16 canales PWM, lo que significa que puedes controlar directamente hasta 16 motores servo. La biblioteca ESP32Servo que estamos utilizando también admite todos los pines PWM, facilitando la adición de más servos a tu proyecto.
Conexiones de múltiples servos
Para agregar otro motor servo a tu circuito, en lugar de alimentarlo a través del pin VIN del ESP32, utilizaremos una fuente de alimentación separada para asegurar que los motores reciban suficiente corriente. Conecta el pin de señal del nuevo servo al GPIO14 del ESP32.
Código Arduino para múltiples servos
Modificaremos el código del ejemplo anterior para que ambos motores servo se muevan de un lado a otro entre 0 y 180 grados de manera independiente.
#include
Servo servo1;
Servo servo2;
int servo1Pin = 13;
int servo2Pin = 14;
int pos = 0;
ESP32PWM pwm;
void setup() {
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
servo1.setPeriodHertz(50);
servo2.setPeriodHertz(50);
servo1.attach(servo1Pin, 500, 2400);
servo2.attach(servo2Pin, 500, 2400);
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) {
servo1.write(pos);
delay(15);
}
for (pos = 0; pos = 0; pos -= 1) {
servo1.write(pos);
delay(15);
}
for (pos = 180; pos >= 0; pos -= 1) {
servo2.write(pos);
delay(15);
}
}
Explicación del código para múltiples servos
En este código, hemos creado dos objetos servo: servo1
y servo2
.
Servo servo1;
Servo servo2;
Se definen dos constantes, servo1Pin
y servo2Pin
, que representan los pines GPIO del ESP32 a los que están conectados los dos servos.
int servo1Pin = 13;
int servo2Pin = 14;
Ambos servos se configuran para funcionar a la frecuencia estándar de 50 Hz utilizando el método setPeriodHertz()
. El método attach()
vincula cada objeto servo a su respectivo pin GPIO.
servo1.setPeriodHertz(50);
servo2.setPeriodHertz(50);
servo1.attach(servo1Pin, 500, 2400);
servo2.attach(servo2Pin, 500, 2400);
La función loop consta de cuatro bucles for
. Los primeros dos se encargan de barrer servo1
y servo2
de 0 a 180 grados, mientras que los últimos dos los regresan a 0 grados.
Avanzando más allá
¿Quieres llevar tu control de servos al siguiente nivel? Puedes aprovechar las capacidades de Wi-Fi integradas del ESP32 para desarrollar una interfaz web. Esto te permitirá ajustar la posición del servo de forma remota desde cualquier dispositivo con un navegador web. Esta funcionalidad abre un montón de ideas de proyectos interesantes, como construir brazos robóticos que puedes controlar a distancia, dispositivos para el hogar inteligente que abren persianas o alimentan a tus mascotas, o incluso animatrónicos con movimientos que puedes controlar desde lejos.
Deja una respuesta
Estos temas te pueden interesar