Calibración Precisa de Servos con Arduino UNO y Shield Adafruit PWM
Componentes y suministros
| Arduino UNO | ×1 |
| Shield Adafruit PWM Servo Driver | ×1 |
| Tornillo M3 | ×8 |
| Arandela M3 | ×8 |
| Convertidor DC-DC Step-down LM2596 | ×1 |
| Filamento PLA Rojo | ×1 |
| Filamento PLA Blanco | ×1 |
| Transportador de 180° transparente | ×1 |
| Potenciómetro rotativo genérico | ×1 |
| Servomotor 9g | ×1 |
Herramientas necesarias
- Impresora 3D genérica
Aplicaciones y servicios en línea
- Arduino IDE
- Autodesk Fusion 360 (diseño de piezas)
Sobre el proyecto
En una publicación anterior en Hackster, mostré un banco de pruebas para comparar servos del mismo lote, demostrando que enviar la misma señal PWM a servos distintos produce diferencias significativas en su posición final.
¿Por qué no usar las librerías de servo existentes para Arduino?
- Con el Adafruit PWM Servo Driver controlo múltiples servos usando solo dos pines (I2C), en lugar de dedicar un pin por servo.
- La librería Servo estándar a veces hace que el servo gire hasta el límite mecánico al enviar posición 0°, dañando los engranajes.
Los servos 9g son baratos y no diseñados para precisión, pero quiero exprimir su rendimiento para un robot caminante, necesitando comportamiento más predecible y preciso.
¿Cómo controlar servos hobby con mayor precisión?
Construí un dispositivo de calibración que combina dos conceptos simples:
- Alinear el servo con el centro de un transportador para medir su posición angular.
- Conectar un potenciómetro a una entrada analógica del Arduino para controlar la posición del servo ajustando el valor PWM mientras giro el eje del potenciómetro.
Usé el Monitor Serial del IDE para leer el valor PWM y anotarlo manualmente. Diseñé en Autodesk 123D un soporte impreso en 3D que sujeta potenciómetro, transportador, servo, Arduino, shield Adafruit y fuente de alimentación.
Construcción del dispositivo
Imprimí las piezas y las uní con tornillos y arandelas M3. Los agujeros de montaje están ajustados a mis componentes; otras piezas pueden requerir modificaciones.
Electrónica: pin central del potenciómetro a A0, los otros a 0V y 5V. Shield PWM sobre Arduino. Convertidor buck LM2596 (ajustado a 5V salida desde 9V entrada). Servo 9g en el primer slot del shield. Subí el sketch al Arduino.
Girando la perilla superior izquierda controlo el servo, y el Monitor Serial muestra el valor PWM para cada ángulo.
¿Qué me dice el dispositivo?
Coloqué el brazo del servo en su límite horario, ligeramente más allá de 180° en el transportador. Luego giré el potenciómetro hasta alinear el brazo con 0°, anoté el PWM. Repetí cada 10° hasta 180°.
Los resultados muestran una relación fuertemente lineal entre PWM y ángulo. Para mi servo: PWM = 2.35 × Ángulo + 159.4.
Ahora tengo dos opciones para control preciso:
- Tabla de búsqueda: Guardar pares (ángulo, PWM) en un array y consultar el PWM para el ángulo deseado (limitado a múltiplos de 10°).
- Regresión lineal: Usar la fórmula calculada para obtener el PWM exacto para cualquier ángulo intermedio.
Ambos métodos mejoran notablemente la precisión. Calibrar cada servo lleva tiempo, pero vale la pena para mi proyecto.
Nota: Al sacar el servo del dispositivo, debe mantenerse el brazo en la misma posición, ya que la calibración depende de su montaje.
Mejoras para la próxima versión
- Mecanismo de liberación rápida para el servo (imanes de neodimio en lugar de tornillos).
- Reducir tamaño reorientando Arduino y fuente.
- Añadir interruptor entre batería y convertidor buck.
- Imprimir el soporte en menos piezas.
- Sustituir lectura manual del transportador por sensor automático de posición angular (elimina error de paralaje).
- Pantalla LCD para mostrar resultados sin necesidad de PC conectada.
Conclusión
Los servos hobby son baratos e imprecisos, pero para muchas aplicaciones son suficientes. Este banco de calibración me permite obtener mayor precisión y repetibilidad, esencial para mi robot caminante.
Código
Sketch para dispositivo calibrador de servos (C/C++)
#include <Adafruit_PWMServoDriver.h>
#define analogIn A0
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
int inputValue = 0;
int tmpPwmValue = 0;
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(60);
}
void loop() {
inputValue = analogRead(analogIn); // 0-1024
// Servo min/max PWM típicos: 100-612
int pwmValue = (int)(100 + (inputValue / 2));
pwm.setPWM(0, 0, pwmValue);
if (pwmValue != tmpPwmValue) {
Serial.print("Potenciómetro = ");
Serial.print(inputValue);
Serial.print(", PWM = ");
Serial.println(pwmValue);
}
tmpPwmValue = pwmValue;
delay(15);
}
Piezas personalizadas y envolventes
Repositorio de piezas para calibrador de servos: https://github.com/jeremylindsayni/ServoCalibrator
Proceso de manufactura
- Seguimiento Facial Pan/Tilt en Tiempo Real en Raspberry Pi – Guía Práctica
- Walbi: Robot Bípede Estable con Arduino y Servos LX-16A
- Brazo Robótico IoT de 5 Grados de Libertad con Arduino Yun y Control Blynk
- Ácido poliláctico (PLA) en impresión 3D: Guía completa para profesionales
- PLA vs ABS vs Nylon: Cómo Elegir el Filamento Adecuado para Impresión 3D
- PLA vs ABS en Impresión 3D: Diferencias Clave y Cuándo Usar Cada Uno
- PLA: ¿Es realmente reciclable y biodegradable?
- ¿Se disuelve el PLA en agua? Condiciones, absorción y cómo hacerlo impermeable
- ¿Puede el Filamento PLA Conducir Electricidad? Variantes Conductivas y Desafíos de Impresión
- Entendiendo la Conductividad del PLA: Propiedades Eléctricas del Filamento de Impresión 3D
- Cambio a accionamientos DC: alternativa fiable a servos AC en control de movimiento industrial