viernes, 6 de febrero de 2015

Arduino: moviendo un servo

Buenas, después de ver como funcionan los leds, pulsadores y pantallas LCD, ahora le toca el turno a los servos.

¿Que es un servo? 
Un servo o servomotor es un dispositivo muy similar a un motor de corriente continua con la
peculiaridad de poder posicionar su eje una posición determinada dentro de un rango de aproximadamente unos 180º. Se puede modificar tanto su posición como velocidad. 

Arduino tiene una biblioteca para este tipo de dispositivos llamada servo.h. Con ella podemos controlar cualquier servo de manera independiente. Hay que tener en cuenta que dependiendo del tipo de servo y de la cantidad de los mismos, seguramente no podrás alimentarlo desde la misma placa de Arduino.

Para este ejemplo y dado que el servo a utilizar es de los más pequeños, no habrá problema ninguno en conectarlo directamente a la placa de arduino.

¿Como trabaja un servo? 
Los servos utilizan la modulación por ancho de pulsos (PWM) para controlar tanto la dirección como la posición del motor de de corriente continua. En su mayoría trabajan a una frecuencia de 50Hz con la señal PWM de un periodo de 20 milisegundos. La electrónica incorporada en estos dispositivos responde al ancho de la señal modulada.

Si recibe una señal de entre 0,5 a 1,4 milisegundos, el servo se moverá en sentido horario.

                _      _     _          _    _    _
               | |    | |   | |        | |  | |  | |
               | |    | |   | |        | |  | |  | |
      _________| |____| |___| |________| |__| |__| |___________

Si la señal es de 1,6 a 2 milisegundo el giro sera antihorario:

                ______      ______     ______     ______    ______
               |      |    |      |   |      |   |      |  |      |
               |      |    |      |   |      |   |      |  |      |
      _________|      |____|      |___|      |___|      |__|      |____

 Y si la señal recibida es de 1,5 milisegundos su estado sera neutro:

                 ___      ___     ___     ___    ___    ___
                |   |    |   |   |   |   |   |  |   |  |   |
                |   |    |   |   |   |   |   |  |   |  |   |
       _________|   |____|   |___|   |___|   |__|   |__|   |_____

La blioteca servo.h:
  • attach(): Fija el pin donde estará conectado el servo
  • writer():Escribe un valor en el servo, controlando su eje en consecuencia. Su valor esta dado en grados de 0 a 180. En un servo de rotación continua cambiara la velocidad del servo, siendo 0 toda la velocidad en una dirección y 180 en otra dirección y un valor de 90 aproximadamente sin movimiento.
  • writeMicroseconds(): Escribe un valor en microsegundos (US)  en el servo controlando su eje en consecuencia. En un servo estándar si el valor del parámetro es 1000 el eje girará completamente a la izquierda, 2000 es completamente a la derecha  y con un valor de 1500 se sitúa en el centro. Según el fabricante estos valores pueden variar, normalmente entre 700 y 2300. Podéis probar pero teniendo en cuenta que llegar al limite puede producir daños en el servo. Normalmente lo sabréis por el ruido que hará el servo. NO ES RECOMENDABLE pasar de esos parámetros ya que pueden producir daños en el servo. Para los servos de rotación continua writeMicroseconds() funciona de una manera análoga a write().

  • read(): Lee el angulo actual del servo (el ultimo valor pasado por la llamada write().
  • attached(): Comprueba si la variable servo esta unida a un pin.
  • detach(): Separa la variable servo de un pin. Si se separan todas las variables de servo, los pines 9 y 10 pueden utilizarse como PWM mediante analogWrite().
Primer programa para un servo, mover el servo de manera simple:





#include "servo.h" 	// Cargamos la biblioteca "Servo.h"
 
int Pin = 9;		// Cargamos un 9 en la variable "Pin"
 
Servo servo1;		// Nombramos al primer servo
  
void setup(){        // Configuración
  
  servo1.attach(Pin);   //Adjuntamos el pin 9 a servo1
} 
 
 
void loop()             //Programa principal
{                                 
    servo1.write(0);     //Mandamos a servo1 a la posición 0 grados      
    delay(1500);         //Hace una pausa de 1,5 segundos
    servo1.write(90);    //Mandamos a servo1 a la posición 90 grados       
    delay(1500);         //Hace una pausa de 1,5 segundos
    servo1.write(180);   //Mandamos a servo1 a la posición 180 grados        
    delay(1500);         //Hace una pausa de 1,5 segundos
    servo1.write(90);    //Mandamos a servo1 a la posición 900 grados       
    delay(1500);         //Hace una pausa de 1,5 segundos
} 


Segundo programa para un servo, mover el servo con pulsadores:




#include "servo.h"

int servovar1=90;   // Indicamos la posicion inicial de servo1
Servo servo1;       // Nombramos al primer servo

int Pulsador1=6;   // Cargamos un 6 en la variable "pulsador1"
int Pulsador2=7;   // Cargamos un 7 en la variable "pulsador2"

void setup() {
  servo1.attach(9);    // Adjuntamos el pin 9 a servo1
  pinMode(Pulsador1, INPUT);  // Pulsador 1 en pin 6 es una entrada
  pinMode(Pulsador2, INPUT);  // Pulsador 2 en pin 7 es una entrada
}

void loop() {
    if(digitalRead(Pulsador1)==HIGH && digitalRead(Pulsador2)==LOW){  
      servovar1++;		// Presionamos el pulsador1 para que vaya a la izquierda
}
    else if(digitalRead(Pulsador1)==LOW && digitalRead(Pulsador2)==HIGH){  
      servovar1--;	// Presionamos el pulsador2 para que vaya a la derecha
    }
  
  servo1.write(servovar1);
  delay(10);	// Pausa de 10 milisegundos (Para más velocidad 
  				// quitar esta linea y para ir más lento aumentar el valor)
}


9 comentarios :

  1. muy bien explicado amigo.

    disculpa soy nuevo con el arduino ¿como le puedo hacer para que la velocidad del servo vaya lento pero sin pulsadores?

    de antemano gracias

    ResponderEliminar
    Respuestas
    1. Buenas!!! para que vaya más lento tienes que aumentar el delay(10); si pones delay(50); por ejemplo, ira más lento. A que te refieres sin pulsadores? en un movimiento de va y ven? Saludos!

      Eliminar
    2. exacto, sin usar pulsadores solo el servo y el arduino que me haga un movimiento de va y ven.

      ya que quiero utilizar un sensor y el comando IF, con este para que el servo se mueva a una velocidad lenta al percibir cierto color.

      Eliminar
    3. Ahá, Bueno para eso se me ocurren varias formas de hacerlo, una es si siempre va a estar el servo en va y ven solo tienes que asignar una variable al delay, sería algo así
      void loop() {

      if (boton1=1) {
      variable_tiempo= 10;
      }
      if (boton2=1) {
      variable_tiempo = 50;
      }
      for (pos = 0; pos <= 180; pos += 1) {
      myservo.write(pos);
      delay(variable_tiempo);
      }
      for (pos = 180; pos >= 0; pos -= 1) {
      myservo.write(pos);
      delay(variable_tiempo);
      }
      }

      con esto consigues que el tiempo de cada paso valga lo que que marque la variable_tiempo.
      ¿puede ser esto lo que necesitas?
      Saludos!!!

      Eliminar
    4. gracias amigo si es lo que estaba buscando te agradezco mucho

      Eliminar
    5. De nada!!! suerte con tu proyecto!!!

      Eliminar
  2. hola, saludos, quería preguntar si hay manera de que un solo interruptor maneje el servo hacia la izquierda o derecha cada vez que la presiono.

    ResponderEliminar
  3. buen post, muy bien explicado. Amigo tengo una consulta como hacer que el servo gire mas lento con un joystick?

    ResponderEliminar