Tutorial - Servomotores analógicos y digitales

TEORÍA DE SERVOMOTORES
Los servomotores son actuadores rotativos o lineales que permiten el control preciso ya sea del ángulo o la posición lineal, velocidad y aceleración. Su construcción básica comprende de un motor con un sensor de posición acoplado al mismo, que sirve como retroalimentación; todo el conjunto es manejado por un controlador o un módulo dedicado para realizar la tarea.
El término Servo es generalmente usado para todo aquel motor que posea un sistema de control de lazo cerrado.

Algunas de las aplicaciones de los mismos se pueden ver en:
# Robótica.
# Maquinaria CNC.
# Manufactura automatizada.

Las partes que construyen un servo motor se pueden dividir en tres:
# ENCODERS : Sirven como retroalimentación, pueden ser construidos tanto por discos ranurados o dentados, potenciómetros o encoders rotativos absolutos o incrementales.
# MOTORES : Generalmente son usados los motores DC que pueden ser controlados con Mosfets para usos de baja potencia y motores AC con variadores de frecuencia para usos industriales.
# CONTROL : Dependiendo de la aplicación y resolución, existen controladores basados en circuitos dedicados o hechos a partir de microcontroladores.


SERVOS ANALÓGICOS Y DIGITALES
Los circuitos de control de servomotores son construidos generalmente a partir de un control proporcional. El ángulo o set point se ingresa por medio de una señal PWM, cuyo margen de operación de trabajo va de 1 a 2 milisegundos. Para determinar el ángulo para la mayoría de servos, se usa la fórmula "t = 1 + ángulo/180" siendo el tiempo en microsegundos y el ángulo en grados.

La cantidad de microsegundos en comparación del ángulo, se puede ver en la siguiente figura:


A diferencia de los servos analógicos, los digitales cuentan con la siguientes ventajas:
# Mayor torque.
# Mayor precisión.
# Tiempo de respuesta menor.
# Posibilidad de cambiar los valores de ángulos mínimo y máximo.

Pero sus desventajas son:
# Mayor costo.
# Mayor consumo de energía.

Todos los servos ya sean digitales o analógicos tienen la misma disposición de pines que en su mayoría son tres:
# Cable negro o marrón : GND.
# Cable rojo : Alimentación de voltaje.
# Cable blanco, amarillo o naranja : Entrada de señal PWM

LIBRERÍA "SERVO"
Esta librería permite que la plataforma Arduino controle servomotores. Los servomotores usualmente van de los 0 a los 180 grados. Esta librería permite trabajar hasta con 12 servomotores en la mayoría de plataformas y 48 en caso del Arduino Mega.

En caso de usar un Arduino UNO o similares, al usar 12 motores la utilización de la función analogWrite() de los pines 9 y 10 son desabilitadas. Para el caso del Arduino Mega al usar más de 12 motores, la utilización de la función analogWrite() de los pines 11 y 12 son desabilitados.

Algunas de las funciones de la librería se explican a continuación:
# Servo nombre : Asigna al nombre las facultades de las funciones de la librería Servo.
# nombre.attach(pin) o nombre.attach(pin, min, max) : Configura la plataforma para el uso del servo para un pin específico. En caso de usar valores máximos y mínimos consideramos lo siguiente:
   * MIN : Es el valor correspondiente en microsegundos a los 0 grados de ángulo (Por defecto es 544).
   * MAX : Es el valor correspondiente en microsegundos a los 180 grados de ángulo (Por defecto es 2400).

# nombre.write(ángulo) : Asigna el valor del ángulo deseado para el servo que puede ir de 0 a 180.
# nombre.writeMicroseconds(microsegundos) : Asgina el valor del ángulo deseado para el servo a partir de los microsegundos como valor "integer" sin decimales. En servos estándar 1000 microsegundos es el extremo antihorario, 1500 microsegundos el medio y 2000 microsegundos es el extremo horario. Fuera de lo escrito, los valores pueden cambiar de fabricante en fabricante y generalmente se encuentran en el rando de los 700 a los 2300 microsegundos.
# nombre.read() : Retorna el último ángulo del servo escrito por la función write(). Nos devuelve un dato "integer" de 0 a 180.
# nombre.attached() : Retorna "true" si el servo está asignado al pin y "falso" en el caso contrario.
# nombre.detach() : Desliga al servo asignado "nombre" del pin. Esto es bueno en caso de querer usar los pines 9 y 10 con las funciones analogWrite().

SERVO ANALÓGICO: TOWER PRO SG90
Uno de los servos de mayor uso comercial de bajo coste son los "Tower Pro SG90".



Sus características principales son las siguientes:
# Torque : 1.8 kg - cm.
# Voltaje : 4.8 a 6 V.
# Posiciones : "0" (1.5 ms), "90" (2 ms) y "-90" (1 ms).
# Ciclo de trabajo : 1 a 2 ms.
# Periodo PWM : 20 ms.
# Disposición de cables : Naranja (Señal PWM), Rojo (VCC) y Marrón (GND).
# Engranes : Nylon

SERVO DIGITAL: LS 0009AF
Un servo digital comercial es el "LS 0009AF", puedes también bajar su "datasheet".



Sus características principales son las siguientes:
# Torque : 1.3 a 1.5 kg - cm.
# Voltaje : 4.8 a 6 V.
# Consumo : 120 a 150 mA. 
# Posiciones : "0" (1.5 ms), "90" (2 ms) y "-90" (1 ms).
# Ciclo de trabajo : 1 a 2 ms
# Periodo PWM : 800 a 2200 microsegundos.
# Disposición de cables : Amarillo (Señal PWM), Rojo (VCC) y Marrón (GND).
# Engranes : Metálicos

PRUEBAS DE PROGRAMACIÓN CON SERVOS Y ALGUNOS TRUCOS
La conexión para las pruebas es la siguiente:

# PIN 11 : Arduino UNO => SEÑAL : Servomotor (Cable naranja o amarillo)
# GND : Arduino UNO  => VCC : Servomotor (Cable rojo)
# 5V : Arduino UNO  => GND : Servomotor (Cable negro)


En este primer programa haremos una prueba introduciendo ángulos a través del Monitor Serial:
/*
   PROGRAMA DE PRUEBA DE SERVOS: SERVOS ANALOGICOS

   CONEXION:
             PWM: Pin 11 del Arduino UNO
             GND: Conectar los dos GND
             VCC: Conectar los dos 5V
   
   En el siguiente programa probaremos la posicon angular de un servo por medio de escritura de su 
   angulo por monitor serial. El angulo inicial es 0 grados.
   
   NOTA: Para el siguiente programa necesitamos la libreria "Servo.h"
   
   Autor: Renato H.
   http://beetlecraft.blogspot.pe/

   El siguiente programa es de uso publico, cualquier modificacion o mal uso del mismo que pudiera 
   ocasionar el mal funcionamiento de la plataforma de uso de la misma no es responsabilidad del autor
*/

#include <Servo.h> // Libreria de manejo de servos

Servo servo_prueba;        // Nombre asignado al servo
const int salida_pwm = 11; // Variable para configuracion del pin de salida de senal PWM
int angulo;                // Variable de almacenamiento del angulo ingresado por Monitor Serial

void setup() {
  Serial.begin(9600);              // Configuracion del puerto serial de comunicacion con la PC
  servo_prueba.attach(salida_pwm); // Configuracion del pin de salida de la senal PWM
  servo_prueba.write(0);           // Angulo inicial 
  
  // Mensaje inicial en el monitor serial
  Serial.println("Escribir la posicion de angulo de 0 a 180: ");
}

void loop() {
  if (Serial.available()) {    // Verificacion que el puerto serial recibe datos                                  
   delay(10);               
   angulo = Serial.parseInt(); // Lee solo los datos tipo int del buffer
   servo_prueba.write(angulo); // Escritura de microsegundos ingresado por Monitor Serial
   
   // Mensaje de confirmacion del angulo ingresado por Monitor Serial
   Serial.print("Posicion angular: "); 
   Serial.print(angulo);
   Serial.println(" grados");
   
    while (Serial.available() > 0){Serial.read();} // Rutina de limpieza del buffer del puerto serial
  }
}
Podemos ver como cambia la posición introduciendo el ángulo.
# -90° que corresponde a la posición 0.
# 0° que corresponde a la posición 90.
#  90° que corresponde a la posición 180.




De la misma manera, podemos obtener el mismo resultado a través de la escritura de microsegundos. Como sabemos nuestro rango va de los 1000 us a los 2000 us según las especificaciones del fabricante.
/*
   PROGRAMA DE PRUEBA DE SERVOS: SERVOS ANALOGICOS

   CONEXION:
             PWM: Pin 11 del Arduino UNO
             GND: Conectar los dos GND
             VCC: Conectar los dos 5V
   
   En el siguiente programa probaremos la posicon angular de un servo por medio de escritura de su 
   posicion angular en microsegundos por monitor serial. El angulo inicial es 0 grados o 1000 us.
   
   NOTA: Para el siguiente programa necesitamos la libreria "Servo.h"
   
   Autor: Renato H.
   http://beetlecraft.blogspot.pe/

   El siguiente programa es de uso publico, cualquier modificacion o mal uso del mismo que pudiera 
   ocasionar el mal funcionamiento de la plataforma de uso de la misma no es responsabilidad del 
   autor
*/

#include <Servo.h> // Libreria de manejo de servos

Servo servo_prueba;        // Nombre asignado al servo
const int salida_pwm = 11; // Variable para configuracion del pin de salida de senal PWM
int usegundos;             // Variable de almacenamiento del microsegundo ingresado por Monitor Serial
float angulo;              // Variable para calculo del angulo a partir de microsegundos

void setup() {
  Serial.begin(9600);                   // Configuracion del puerto serial de comunicacion con la PC
  servo_prueba.attach(salida_pwm);      // Configuracion del pin de salida de la senal PWM
  servo_prueba.writeMicroseconds(1000); // Posicion angular inicial de 1000 us
 
  // Mensaje inicial en el monitor serial
  Serial.println("Escribir la posicion angular en microsegundos de 1000 a 2000: ");
}

void loop() {
  if (Serial.available()) {       // Verificacion que el puerto serial recibe datos                                  
   delay(10);               
   usegundos = Serial.parseInt(); // Lee solo los datos tipo int del buffer
   servo_prueba.writeMicroseconds(usegundos); // Escritura del angulo ingresado por Monitor Serial
   
   // angulo por interpolacion 
   // angulo = 0 + (usegundos - 1000)*(180 - 0)/(2000 - 1000);
   angulo = 0 + (usegundos - 1000) * 0.18;
   
   // Mensaje de confirmacion del angulo ingresado por Monitor Serial
   Serial.print("Posicion en microsegundos: "); 
   Serial.print(usegundos);
   Serial.print(" us || ");
   Serial.print("Posicion angular: ");
   Serial.print(angulo,0);
   Serial.println(" grados");
   
    while (Serial.available() > 0){Serial.read();} // Rutina de limpieza del buffer
  }
}
Ahora probamos tres diferentes posiciones:
# 1000 us que corresponde a -90° o la posición 0.
# 1500 us que corresponde a 0° o la posición 90.
# 2000 us que corresponde a 90° o la posición 180.




Como se observa en las figuras anteriores, en comparación de usar los ángulos para el caso de los microsegundo se tiene que tener más cuidado; y es preferible hacer pruebas de ajuste para tener una mayor precisión de la posición angular (Es recomendable usar las especificaciones como referencia).

Usando el mismo programa modificado para no tener el valor del ángulo podemos ajustar el ángulo y la posición física del brazo, todo ello para tener una mayor precisión de la posición angular.
/*
   PROGRAMA DE PRUEBA DE SERVOS: SERVOS ANALOGICOS

   CONEXION:
             PWM: Pin 11 del Arduino UNO
             GND: Conectar los dos GND
             VCC: Conectar los dos 5V
   
   En el siguiente programa probaremos la posicon angular de un servo por medio de escritura de su 
   posicion angular en microsegundos por monitor serial. El angulo inicial es 0 grados o 1000 us.
   
   NOTA: Para el siguiente programa necesitamos la libreria "Servo.h"
   
   Autor: Renato H.
   http://beetlecraft.blogspot.pe/

   El siguiente programa es de uso publico, cualquier modificacion o mal uso del mismo que pudiera 
   ocasionar el mal funcionamiento de la plataforma de uso de la misma no es responsabilidad del 
   autor
*/

#include <servo .h> // Libreria de manejo de servos

Servo servo_prueba;        // Nombre asignado al servo
const int salida_pwm = 11; // Variable para configuracion del pin de salida de senal PWM
int usegundos;             // Variable de almacenamiento del microsegundo ingresado por Monitor Serial

void setup() {
  Serial.begin(9600);                   // Configuracion del puerto serial de comunicacion con la PC
  servo_prueba.attach(salida_pwm);      // Configuracion del pin de salida de la senal PWM
 
  // Mensaje inicial en el monitor serial
  Serial.println("Escribir la posicion angular en microsegundos: ");
}

void loop() {
  if (Serial.available()) {       // Verificacion que el puerto serial recibe datos                                  
   delay(10);               
   usegundos = Serial.parseInt(); // Lee solo los datos tipo int del buffer
   servo_prueba.writeMicroseconds(usegundos); // Escritura del angulo ingresado por Monitor Serial
   
   // Mensaje de confirmacion del angulo ingresado por Monitor Serial
   Serial.print("Posicion en microsegundos: "); 
   Serial.print(usegundos);
   Serial.println(" us");
   
    while (Serial.available() > 0){Serial.read();} // Rutina de limpieza del buffer
  }
}
El resultado es el siguiente:



De esa manera podemos modificar el programa anterior. De esa manera, la modificación al programa es la siguiente:
/*
   PROGRAMA DE PRUEBA DE SERVOS: SERVOS ANALOGICOS

   CONEXION:
             PWM: Pin 11 del Arduino UNO
             GND: Conectar los dos GND
             VCC: Conectar los dos 5V
   
   En el siguiente programa probaremos la posicon angular de un servo por medio de escritura de su 
   posicion angular en microsegundos por monitor serial. El angulo inicial es 0 grados o 545 us.
   
   NOTA: Para el siguiente programa necesitamos la libreria "Servo.h"
   
   Autor: Renato H.
   http://beetlecraft.blogspot.pe/

   El siguiente programa es de uso publico, cualquier modificacion o mal uso del mismo que pudiera 
   ocasionar el mal funcionamiento de la plataforma de uso de la misma no es responsabilidad del 
   autor
*/

#include <Servo.h> // Libreria de manejo de servos

Servo servo_prueba;        // Nombre asignado al servo
const int salida_pwm = 11; // Variable para configuracion del pin de salida de senal PWM
int usegundos;             // Variable de almacenamiento del microsegundo ingresado por Monitor Serial
float angulo;              // Variable para calculo del angulo a partir de microsegundos

void setup() {
  Serial.begin(9600);                   // Configuracion del puerto serial de comunicacion con la PC
  servo_prueba.attach(salida_pwm);      // Configuracion del pin de salida de la senal PWM
  servo_prueba.writeMicroseconds(545);  // Posicion angular inicial de 545 us
 
  // Mensaje inicial en el monitor serial
  Serial.println("Escribir la posicion angular en microsegundos de 545 a 2250: ");
}

void loop() {
  if (Serial.available()) {       // Verificacion que el puerto serial recibe datos                                  
   delay(10);               
   usegundos = Serial.parseInt(); // Lee solo los datos tipo int del buffer
   servo_prueba.writeMicroseconds(usegundos); // Escritura del angulo ingresado por Monitor Serial
   
   // angulo por interpolacion 
   // angulo = 0 + (usegundos - 545)*(180 - 0)/(2250 - 545);
   angulo = (usegundos - 545) * 0.1056;
   
   // Mensaje de confirmacion del angulo ingresado por Monitor Serial
   Serial.print("Posicion en microsegundos: "); 
   Serial.print(usegundos);
   Serial.print(" us || ");
   Serial.print("Posicion angular: ");
   Serial.print(angulo,0);
   Serial.println(" grados");
   
    while (Serial.available() > 0){Serial.read();} // Rutina de limpieza del buffer
  }
}
El resultado en el Monitor Serial es el siguiente:


A partir de lo que sabemos ahora, podemos combinar las dos aproximaciones y usarlos en parametrizar el servo usando la función "nombre_servo.attach(pin, min, max)". De esta manera, el programa inicial se puede modificar y quedaría de la siguiente manera:
/*
   PROGRAMA DE PRUEBA DE SERVOS: SERVOS ANALOGICOS

   CONEXION:
             PWM: Pin 11 del Arduino UNO
             GND: Conectar los dos GND
             VCC: Conectar los dos 5V
   
   En el siguiente programa probaremos la posicon angular de un servo por medio de escritura de su 
   angulo por monitor serial. El angulo inicial es 0 grados.
   
   NOTA: Para el siguiente programa necesitamos la libreria "Servo.h"
   
   Autor: Renato H.
   http://beetlecraft.blogspot.pe/

   El siguiente programa es de uso publico, cualquier modificacion o mal uso del mismo que pudiera 
   ocasionar el mal funcionamiento de la plataforma de uso de la misma no es responsabilidad del autor
*/

#include <Servo.h> // Libreria de manejo de servos

Servo servo_prueba;        // Nombre asignado al servo
const int salida_pwm = 11; // Variable para configuracion del pin de salida de senal PWM
int angulo;                // Variable de almacenamiento del angulo ingresado por Monitor Serial

void setup() {
  Serial.begin(9600); // Configuracion del puerto serial de comunicacion con la PC
  servo_prueba.attach(salida_pwm, 545, 2250); // Configuracion del pin de salida de la senal PWM
  servo_prueba.write(0); // Angulo inicial 
  
  // Mensaje inicial en el monitor serial
  Serial.println("Escribir la posicion de angulo de 0 a 180: ");
}

void loop() {
  if (Serial.available()) {    // Verificacion que el puerto serial recibe datos                                  
   delay(10);               
   angulo = Serial.parseInt(); // Lee solo los datos tipo int del buffer
   servo_prueba.write(angulo); // Escritura de microsegundos ingresado por Monitor Serial
   
   // Mensaje de confirmacion del angulo ingresado por Monitor Serial
   Serial.print("Posicion angular: "); 
   Serial.print(angulo);
   Serial.println(" grados");
   
    while (Serial.available() > 0){Serial.read();} // Rutina de limpieza del buffer del puerto serial
  }
}
Los resultados del programa son los siguientes:

 



Autor: 

No hay comentarios:

Publicar un comentario