Brazo robótico con ESP32 y servos | Guía intermedia
Monta un brazo de 4 ejes con ESP32, un driver PCA9685 y servos MG996R/SG90. El cálculo de par, el presupuesto de corriente y el cableado explicados, con el código que te escribe la IA.
- Nivel
- Intermedio
- Tiempo
- Un fin de semana (6-8 h)
- Publicada
| Componente | Cant. | Precio aprox. |
|---|---|---|
| ESP32 DevKitC (ESP32-WROOM-32, 30 pines) | 1 | 6-12 € |
| Driver PWM/servos PCA9685 (16 canales, I2C, clon genérico) | 1 | 3-5 € |
| Servo MG996R (engranajes metálicos, alto par) | 3 | 5-7 €/ud |
| Micro servo SG90 (para la pinza) | 1 | 2-3 € |
| Kit mecánico de brazo de 4 ejes (acrílico o aluminio, con brackets y tornillería, sin electrónica) | 1 | 20-35 € |
| Fuente de alimentación conmutada 5V 5A con conector jack | 1 | 8-12 € |
| Adaptador de conector jack DC a regleta de terminales | 1 | 1-2 € |
| Condensador electrolítico 1000 µF 16V | 1 | 0.50 € |
| Interruptor de palanca (corte de la línea V+, para el paro de emergencia) | 1 | 1-2 € |
| Cables dupont macho-macho y macho-hembra, más bridas | 1 | 3-4 € |
Cómo funciona
El ESP32 genera sin problema la señal PWM de cada servo, pero no puede darles la corriente que piden bajo carga: 3 servos MG996R sosteniendo el brazo extendido llegan a pedir hasta 2,5 A cada uno si se bloquean, muy por encima de lo que aguanta el regulador de la placa. Por eso metes un PCA9685 en medio: recibe la orden por I2C desde el ESP32 a 3,3V (sin tocar pines de arranque ni de solo entrada) y saca el PWM con su propia alimentación de servos, el V+ de hasta 6V, separada por completo de la lógica. El servo más fuerte va en la base y el hombro, donde el brazo hace más palanca contra la gravedad. El más débil va en la pinza, que solo tiene que apretar un objeto pequeño.
El montaje
¿Por qué un brazo robótico y no otro robot móvil? Porque aquí el reto no es moverte por el suelo, es mover peso en el aire sin que nada se caliente, se pare en seco o se te resetee solo. Si ya has cableado un Arduino y sabes lo que es una fuente externa, este es el salto lógico: varios motores, una sola fuente compartida y un driver en medio que hace de intermediario. En mi caso, el brazo de 4 ejes es el proyecto que más enseña sobre presupuesto de corriente porque los números fallan rápido si no los haces bien.
Qué vas a montar y qué necesitas saber ya
Un brazo de 4 grados de libertad: base (gira el brazo entero), hombro, codo y pinza. Cuatro servos, un driver PCA9685 que habla por I2C con el ESP32, y una fuente aparte que alimenta solo los servos.
Esta guía asume que ya sabes soldar lo básico, cablear con dupont sin liarte, y subir un sketch desde el Arduino IDE (o PlatformIO) a un ESP32. Necesitas también un multímetro para comprobar tensión y continuidad antes de dar corriente, un destornillador pequeño para los tornillos de los servos y de la regleta de terminales, y paciencia para la calibración: cada servo barato responde un poco distinto al mismo pulso.
Por qué el ESP32 no toca la alimentación de los servos
Aquí está el error que se come más placas: conectar el cable rojo de un servo al pin de 5V o 3V3 del ESP32. No lo hagas. Dos motivos, uno de tensión y otro de corriente.
El ESP32 trabaja a 3,3V y sus pines no son tolerantes a 5V: la propia documentación de Espressif marca el límite en 3,6V, así que cualquier cosa por encima necesita un divisor de tensión antes de tocar un GPIO. La señal PWM del servo no es el problema (un pulso de 3,3V ya se lee como HIGH en la entrada de la mayoría de servos), el problema es la corriente: el regulador que trae la placa del ESP32 para sacar 3,3V desde el USB da como mucho unos cientos de mA, pensados para alimentar el propio chip y algún sensor pequeño. Un servo MG996R bajo carga real pide entre 500 y 900 mA, y si se bloquea contra un tope llega a 2,5 A. Tres de esos servos sostenidos por un regulador pensado para el propio microcontrolador no funcionan, y en el mejor de los casos el ESP32 se reinicia solo cuando arrancan los servos porque le estás robando la tensión que necesita para mantenerse encendido.
Por eso el PCA9685 tiene dos alimentaciones separadas y es la pieza clave del montaje:
- VCC (lógica): la conectas al 3,3V del ESP32. Solo alimenta el chip del driver, que consume unos pocos mA, así que no supone ninguna carga real para el regulador.
- V+ (potencia de los servos): la conectas a la fuente externa de 5V 5A, por su propio terminal de tornillo. Esta es la que de verdad mueve los motores.
Las dos alimentaciones comparten la masa (GND) entre ESP32, PCA9685 y la fuente externa. Es el punto que más gente se salta y el que más falla explica: sin una masa común, la señal PWM no tiene una referencia de 0V compartida y el servo no sabe interpretar el pulso, se mueve a tirones o directamente no responde.
Un capacitor de 1000 µF en el terminal V+ (entre positivo y GND, lo más cerca posible de la regleta) no es opcional aquí: cuando un servo arranca o cambia de dirección de golpe pide un pico de corriente que la fuente no siempre entrega al instante, y el condensador actúa de colchón para ese pico. Sin él, notarás el ESP32 reiniciarse o el PCA9685 perder la conexión I2C justo cuando un servo se mueve.
El par por la palanca: qué servo va dónde
¿Por qué el MG996R en la base y el hombro, y el SG90 solo en la pinza? Por física de palanca, no por gusto.
El hombro tiene que sostener todo lo que cuelga después de él: el servo del codo (unos 55 g), la estructura del antebrazo, el servo de la pinza (9 g) y lo que agarres. Con el brazo extendido en horizontal, el peso equivalente ronda los 170-180 g a unos 15 cm del eje del hombro. Multiplica peso por distancia y te da el par que necesita el servo: 0,18 kg × 15 cm ≈ 2,6 kgf·cm de par mínimo solo para sostenerse, sin ni siquiera moverse. El MG996R da entre 9,4 kgf·cm (a 4,8V) y 11 kgf·cm (a 6V) de par de bloqueo según su hoja de datos, así que te queda un margen de 3,5 a 4 veces: necesario porque acelerar y frenar el brazo pide más par que solo sostenerlo quieto.
El codo sostiene menos (solo la pinza y lo que agarra, unos 90 g a 12 cm del eje, ≈1,1 kgf·cm), así que en teoría un servo más pequeño le sobraría. Se mantiene el MG996R igual por dos motivos prácticos: simplifica la compra (un solo modelo, una sola calibración) y la diferencia de precio con un servo más débil es de un par de euros, no merece la pena complicar el BOM por eso.
La pinza (SG90) solo tiene que cerrar sus dedos sobre un objeto pequeño, no sostener el brazo. Su par de bloqueo es de 1,8 kgf·cm (a 4,8V), muy por debajo de los 2,6 kgf·cm que hace falta en el hombro. Si pruebas a poner un SG90 ahí, el servo se bloquea, tira toda su corriente de bloqueo de forma continua para intentar sostener un peso que no puede, se calienta y con el tiempo pela los dientes de plástico del engranaje. Este es el motivo real por el que el servo fuerte va cerca de la base y el débil al final del brazo, no una convención que se copia sin pensar.
Cableado, pin a pin
| Señal | ESP32 | Va a |
|---|---|---|
| Lógica (VCC) | 3V3 | PCA9685 VCC |
| Masa | GND | PCA9685 GND + GND de la fuente 5V |
| I2C datos | GPIO21 (SDA) | PCA9685 SDA |
| I2C reloj | GPIO22 (SCL) | PCA9685 SCL |
| PCA9685 | Va a |
|---|---|
| V+ (terminal) | + de la fuente 5V/5A, a través del interruptor |
| GND (terminal) | - de la fuente 5V/5A |
| OUT0 | Servo base (MG996R) |
| OUT1 | Servo hombro (MG996R) |
| OUT2 | Servo codo (MG996R) |
| OUT3 | Servo pinza (SG90) |
GPIO21 y GPIO22 son los pines de I2C por defecto del ESP32 y no son pines de arranque (strapping): esos son GPIO0, GPIO2, GPIO5, GPIO12 y GPIO15, y conviene dejarlos libres para no interferir con el arranque de la placa. Si más adelante añades finales de carrera o potenciómetros de control manual, usa los pines GPIO32-39: son de entrada en el rango ADC1, aunque recuerda que GPIO34-39 son solo entrada, no sirven para sacar señal.
Montaje mecánico: el orden importa
Antes de atornillar nada, centra cada servo por software (mándale la orden de 90 grados desde un sketch mínimo) y solo entonces coloca el brazo de plástico (el horn) en el eje, alineado con la posición que quieres que sea el centro mecánico del recorrido. Si atornillas el horn antes de centrar el servo, el eje puede quedar desplazado y el brazo choca contra un tope mecánico por un lado mucho antes de lo que debería, lo que en la práctica es forzar al servo contra un obstáculo cada vez que se acerca a ese extremo. Es el fallo mecánico más común en estos kits y parece un problema de software cuando en realidad es un tornillo mal puesto.
Monta de la base hacia la pinza y deja hueco de sobra en el cableado de cada articulación: los cables de los servos tienen que poder seguir el giro completo del eje sin tensarse ni engancharse en la estructura. Usa las bridas para agrupar los cables a lo largo del brazo pero sin apretarlos del todo en las zonas donde hay movimiento.
Calibración y control de corriente
Los servos baratos varían de unidad a unidad aunque sean el mismo modelo: el mismo valor de pulso no coloca dos MG996R exactamente en el mismo ángulo. Por eso el software no manda un ángulo directo, manda un rango de ticks del PCA9685 (12 bits, 0 a 4095 a 50 Hz) que tienes que calibrar por servo, moviéndolo a los extremos y anotando los valores donde deja de girar sin forzar el tope mecánico.
La otra parte de la calibración es de corriente, no de ángulo: si mueves un servo de golpe de 0 a 180 grados, el pico de corriente de arranque se suma al de los demás servos si se mueven a la vez. La solución no es una fuente más grande, es mover en pasos pequeños con una pausa entre cada uno, así el consumo se reparte en el tiempo en vez de llegar todo junto.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);
void moverSuave(uint8_t canal, int desde, int hasta) {
int paso = (hasta > desde) ? 1 : -1;
for (int angulo = desde; angulo != hasta; angulo += paso) {
int ticks = map(angulo, 0, 180, 150, 600); // calibra estos límites por servo
pwm.setPWM(canal, 0, ticks);
delay(15);
}
}
void setup() {
Wire.begin(21, 22);
pwm.begin();
pwm.setPWMFreq(50); // servos analógicos y digitales estándar van a 50 Hz
}
void loop() {
moverSuave(1, 90, 45); // canal 1 = hombro, de 90 a 45 grados
delay(1000);
}
Con presupuesto de corriente en reposo (los 4 servos sosteniendo posición sin bloquearse) ronda los 2,4 A: unos 700 mA por cada MG996R más unos 300-500 mA del SG90 (las specs de los clones SG90 varían bastante entre fabricantes, usa el dato más alto que encuentres en el datasheet de tu unidad concreta para no quedarte corto). Si un servo se bloquea, ese consumo sube hasta 2,5 A solo en ese eje. En el peor caso teórico, los 4 servos bloqueados a la vez piden unos 8 A, algo que no debería pasar en uso normal (solo ocurre si mandas un ángulo imposible o el brazo choca contra un tope físico), pero es la razón por la que la fuente de 5A y el condensador de 1000 µF trabajan juntos: la fuente cubre el consumo típico con margen, y el condensador absorbe el pico corto mientras la fuente reacciona.
Seguridad
- Calor real, no solo un decir: un servo bloqueado durante minutos (sosteniendo más peso del que puede, o empujando contra un tope) calienta el bobinado y puede quemar el motor o pelar el engranaje. Prueba primero sin carga, con el brazo vacío, y no dejes el brazo encendido y bloqueado sin vigilancia.
- Pinzamiento: con 9-11 kgf·cm de par en el hombro y el codo, el brazo aprieta con fuerza de verdad. Mantén los dedos lejos del recorrido de las articulaciones, sobre todo la primera vez que pruebas un rango de movimiento nuevo.
- Cortos en la regleta: el terminal V+ del PCA9685 y la regleta de la fuente quedan con tornillos expuestos. Aísla los extremos de cable pelado y comprueba con el multímetro que no hay continuidad entre V+ y GND antes de encender nada.
- El interruptor de corte va en la línea V+: así puedes cortar la alimentación de los servos de golpe sin tener que desenchufar el ESP32 (que puede seguir conectado al PC para ver el monitor serie mientras diagnosticas un problema).
Si quieres ajustar el presupuesto
Más barato: si el brazo es muy ligero (impreso en PLA, sin pinza ni carga real), puedes sustituir los MG996R por SG90 en los 4 ejes. Antes de hacerlo repite el cálculo de par con el peso real de tu brazo: si el resultado supera 1,8 kgf·cm en algún eje, el SG90 no aguanta ahí.
Más cuidado: la versión original de Adafruit del PCA9685 (unos 13-15 €, frente a los 3-5 € del clon genérico) trae mejor documentación y serigrafía en la placa, útil si es tu primer driver I2C. Para más autonomía, cambia la fuente de pared por una batería LiPo 2S (7,4V) con un reductor (UBEC) a 5V 5A: si vas por ahí, nunca cargues la LiPo sin un cargador balanceador, no la perfores ni la dobles, y guárdala en una bolsa ignífuga mientras carga.
Sé que ver “presupuesto de corriente” y “par por palanca” de golpe impone. Tranquilo: monta un eje, prueba que se mueve solo con su servo calibrado, y añade el siguiente. Cuando los 4 ejes muevan la pinza hasta donde tú decidas, ya tienes la base para meterle cinemática inversa o control remoto, que es el paso lógico de aquí al proyecto avanzado.
El software (lo escribe la IA)
El firmware hace tres cosas: inicializa el PCA9685 por I2C, calibra el rango de pulso de cada servo (varía de unidad a unidad, aunque sean el mismo modelo) y mueve cada eje en pasos pequeños en vez de saltos, para no disparar la corriente de golpe. Pídeselo a la IA con este prompt: 'Código para ESP32 con la librería Adafruit_PWMServoDriver, PCA9685 en la dirección I2C 0x40 (SDA en GPIO21, SCL en GPIO22), 4 servos en los canales 0 a 3 (base, hombro, codo, pinza), que mueva cada servo en pasos de 1 grado con una pequeña espera entre pasos hasta llegar al ángulo objetivo.' Revisa que los canales y los límites de ángulo coincidan con tu montaje real antes de subirlo.