Servos en Arduino

Servos en Arduino

Un servo es un tipo de motor ampliamente empleado en electrónica. A diferencia de otros tipos de motores en los que controlamos la velocidad de giro, en un servo indicamos directamente el ángulo deseado y el servo se encarga de posicionarse en este ángulo.

Típicamente los servos disponen de un rango de movimiento de entre 0 a 180º. Es decir, NO son capaces de dar la vuelta por completo (de hecho disponen de topes internos que limitan el rango de movimiento)

Internamente un servo frecuentemente consta de un mecanismo reductor. Por tanto proporcionan un alto par y un alto grado de precisión (incluso décimas de grado). Por contra, las velocidades de giro son pequeñas frente a los motores de corriente continua.

Los servos se admiten una tensión de alimentación entre 4,8V a 7,2V, siendo el valor más adecuado es 6V. Con tensiones inferiores el motor tiene menos fuerza y velocidad. Con tensiones superiores a 6,5V los servos empiezan a oscilar demasiado, lo cual los hace poco útiles.

¿CÓMO FUNCIONA UN SERVO?

Internamente un servo está constituido por un motor de corriente continua, acoplado a un reductor para reducir la velocidad de giro, junto con la electrónica necesaria para controlar su posición.

Frecuentemente simplemente se dispone de un potenciómetro unido al eje del servo, que permite al servo para conocer la posición del eje. Esta información es tratada por un controlador integrado que se encarga de ajustar actuar sobre el motor para alcanzar la posición deseada.

La comunicación de la posición deseada se realiza mediante la transmisión de un señal pulsada con periodo de 20ms. El ancho del pulso determina la posición del servo.

La relación entre el ancho del pulso y el ángulo depende del modelo del motor. Por ejemplo, algunos modelos responden con 0º a un pulso de 500 ms, y otros a un pulso de 1000 ms

En general, en todos los modelos:

  • Un pulso entre 500-1000 us corresponde con 0º
  • Un pulso de 1500 ms corresponde con 90º (punto neutro)
  • Un pulso entre 2000-2500us corresponde con 180º

Por tanto, variando la señal en microsegundos podemos disponer de una precisión teórica de 0.18-0.36º, siempre que la mecánica del servo acompañe.

ESQUEMA DE MONTAJE

Conectar un servo a Arduino es sencillo. El servo dispone de tres cables, dos de alimentación (GND y Vcc) y uno de señal (Sig).

El color de estos cables suele tener dos combinaciones:

Marrón (GND), Rojo (Vcc) y Naranja (Sig)

Negro (GND), Rojo (Vcc) y Blanco (Sig)

Por un lado, alimentamos el servo mediante el terminal GND ( Marrón / Negro) y Vcc (Rojo).

En general, la alimentación a los servos se realizará desde una fuente de tensión externa (una batería o fuente de alimentación) a una tensión de 5V-6.5V, siendo 6V la tensión idónea.

Arduino puede llegar a proporcionar corriente suficiente para encender un servo pequeño (modelo SG90), suficiente para hacer unos cuantos proyectos de prueba.

Sin embargo no dispone de corriente suficiente para actuar un servo grande (MG996R). Incluso varios servos pequeños, o hacer excesiva fuerza con ellos puede exceder la capacidad de corriente de Arduino, provocando su reinicio.

Por otro lado, finalmente, para el control conectamos el cable de señal (naranja / blanco) a cualquier pin digital de Arduino.

 

EJEMPLOS DE CÓDIGO

El control de servos en Arduino es muy sencillo, ya que el IDE Standard proporciona la librería “servo.h”, que permite controlar simultáneamente hasta 12 servos en Arduino Uno/Nano y hasta 48 servos en Arduino Mega.

Entre los ejemplos típicos para ilustrar el funcionamiento de servos tenemos el Sketch “Sweep”, que realiza un barrido continuo con el servo.

Para ello incrementa el ángulo de 0 a 180º a razón de 1º cada 15ms, posteriormente realiza la operación contraria de 180º a 0º, para finalmente reiniciar el bucle.

 

1) Mover un Servo

Código

#include <Servo.h>
 
Servo myservo;  // crea el objeto myservo 
int pos = 0;    // posicion del myservo
 
void setup() {
   myservo.attach(9);  // vincula el myservo al pin digital 9
}
 
void loop() {
   // Posiciona a su máxima velocidad, el Servo en la posición 180
   myservo.write(180);              

   // Vuelve a la posición CERO, con esperas de 20ms
   for (pos = 180; pos >= 0; pos -= 1) 
   {
      myservo.write(pos);              
      delay(20);                       
   }
}

 

2) Mover un Servo desde un LDR

En el siguiente cuadro presiona “Start Simulation” y luego presiona el deslizador del LDR para que el servo se mueva.

 

 

#include <Servo.h>

const int LDRpin = A0;   //Pin del LDR
const int Vminimo = 900;  //Valor mínimo por el cual movemos el Servo

Servo myservo;  // crea el objeto myservo 
int pos = 0;    // posicion del myservo
int V;			// lectura del LDR

 
void setup() {
   myservo.attach(9);  // vincula el myservo al pin digital 9
  Serial.begin(9600);
}
 
void loop() {
   V = analogRead(LDRpin);
     Serial.print("A0 = ");   
   Serial.println(V);
   if (V > Vminimo) {
	   	// Posiciona a su máxima velocidad, el Servo en la posición 180
   		myservo.write(180);
   } else {
	   	// Vuelve a la posición CERO, con esperas de 20ms
   		myservo.write(0);
   }
  delay(200);
}

 

DESAFIO:
Mejora el código según el siguiente problema: “Ocurre que tanto por el “if” que como por el “else” estamos moviendo el servo con la sentencia myservo.write(<pos>);
Esto significa que nunca está teniendo un descanso, siempre le estamos dando una orden al motor. Cambia el código para que si no cambia de estado el LDR, no se mueva el servo.