bclose

Conociendo los servos

Arduino con servo y potenciometro

Objetivos

 

 

    • Que es un servo.
    • Comprender la diferencia con un motor normal.
    • Introducir el concepto de librería en C++.
    • La función map().

 

Material requerido.

 

  Tienda España Tienda Mexico
Kit Arduino Uno  Kit inicio UNO Kit inicio UNO
Kit Arduino MEGA Kit Inicio Mega Kit Inicio Mega

 

Que es un servo

.

Normalmente los motores habituales lo que hacen es transformar la energía eléctrica (O química) en un giro continuo que podemos usar para desarrollar trabajo mecánico.

En la sesión 13 utilizamos un pequeño motor de corriente continua y regulamos la velocidad de giro mediante una señal PWM de Arduino uno.

Los servos son también motores de corriente continua, pero en lugar de diseñarse para obtener un giro continuo que podamos aprovechar (para mover una rueda por ejemplo), se diseñan para que se muevan un angulo fijo en respuesta a una señal de control, y se mantengan fijos en esa posición.

Imaginad por ejemplo un timón de un avión o barco. No queremos un giro continuo, sino un motor al que le pueda indicar el ángulo que deseamos en grados y que mantenga esa orientación hasta que le demos una orden en contrario.

Estos servos o servomotores son muy frecuentes en Aero modelismo y en robótica, por la capacidad que presentan para moverse a un ángulo concreto y mantenerse allí. De hecho se suelen diseñar para que giren un ángulo proporcional a una señal PWM, de forma que su control es muy preciso. Un servo suele estar formado por:

Interior de un servo

Un servo suele estar formado por:

  • Una reductora.Un circuito de control..
  • Un motor de CC.
  • Un circuito de control

En la práctica se comporta como un bloque funcional que posiciona su eje en un ángulo preciso en función de la señal de control

 

Habitualmente los servos tiene un margen de operación, es decir, pueden moverse entre 0º y ángulo dado, que suele ser de 180º, pero existen modelos comerciales de todas la características imaginables (incluyendo servos de 360º).

Normalmente estos pequeños servos funcionan sobre 5V y el control se realiza mediante una señal de control PWM, en la que el ancho el pulso indica el ángulo que deseamos adopte el eje.

Un servo tiene un conector de 3 hilos, 5V (rojo), GND (negro o marrón) y el otro Control (amarillo o blanco).

Podríamos escribir un pequeño programa en Arduino que controle estos pulsos y los relacione con el ángulo buscado, pero antes de que nadie se asuste, los servos (y otras cosas) son tan habituales, que ya ha habido gente que han escrito estos programas y los han puesto a nuestra disposición.

De este modo podemos manejar un servo sin preocuparnos para nada de cómo realizar el control de las señales, o de la operación interna, basta con instalar estos programas en una forma especial llamada librería.

 
  • Una librería es un conjunto de definiciones y funciones escritas en C++ de Arduino, que podemos utilizar en nuestros programas. Podemos ver el código de estos programas, aunque normalmente se requiere un nivel medio alto en C++ para comprender su funcionamiento.
 

La ventaja de trabajar con una plataforma tan bien establecida como Arduino, es que hay cantidad de gente en el mundo desarrollando librerías, casi para cualquier cosa que podáis imaginar.

Y aún hay algo mejor: Son gratis.

Veréis que en las próximas sesiones vamos a utilizar librerías para cantidad de cosas, pero hoy vamos a comenzar con la primera, la librería servo.

 

Usando nuestra primera librería: Servo

.

Servo es una librería estándar en Arduino. Eso quiere decir que viene incluida cuando instaláis el IDE, a diferencia de otras librerías que debemos buscar, descargar de Internet e instalar para poder usarlas.

Para usar una librería estándar, basta con pedirle al IDE que la incluya en nuestro programa. Id al menú Programa \ Importar Librería y os saldrá un desplegable con todas las librerías que tenéis instaladas en el IDE.

Por ahora solo nos interesa la librería Servo. Pinchad en ella. Arduino incluirá una línea al principio de vuestro programa como esta:

#include <Servo.h>

A partir de ahora ya podemos utilizar las funciones disponibles en la librería.

 
  • Normalmente para usar una librería hay que leer la documentación, en la que se detalla la forma de usarla, que funciones tenemos disponibles, que parámetros pasarlas…etc.
  • Como es vuestra primera librería, y nosotros ya nos hemos leído el manual, vamos a llevaros de la mano. Veréis que es de lo más fácil.
 

Vamos a montar un circuito en el que hagamos moverse al servo de forma controlada, e iremos viendo las instrucciones necesarias.

Esquema electrónico del circuito

.

Vamos a conectar el servo primero a GND y 5V y luego el pin de control, a un pin de Arduino que permita PWM (Recordad esto o de lo contrario os costara ver el problema). Recordad que es el ancho el pulso lo que controla el ángulo.

Vamos también a conectar un potenciómetro a la puerta A0 para jugar con el servo.

Esquema electronico

 

El diagrama de conexión para la protoboard es igual de sencillo:

Protoboard

 

El Programa de control

 

Vamos a empezar con una línea que ya conocíamos el include y otra nueva:

#include <Servo.h>
Servo servo1;

Para poder utilizar la librería debemos crear, lo que se conoce como un objeto tipo Servo que llamamos servo1.

C++ es un lenguaje orientado a objetos, esto significa que podemos definir objetos tipo (como servos) sin más que declarar un nuevo objeto del tipo que deseamos. En la jerga de la programación se llama crear una instancia, o instanciar un nuevo objeto.

Así, esa segunda línea significa que vamos a crear una nueva instancia de tipo Servo que llamamos servo1.

 
  • Aunque ahora os pueda parecer una forma extraña de hacer las cosas, la programación orientada a objetos (OOP por sus siglas en inglés), es una de las metodologías más potentes de las ciencias de computación actuales y todos los lenguajes de programación que se precien, han incorporado las ideas de la OOP.
  • Entrar en la teoría del OOP, desborda con mucho las pretensiones de este humilde tutorial de Arduino, por ahora nos limitaremos a mostraros como usar los objetos

Una vez creada la instancia del objeto (y podemos crear tantas como necesitemos, para manejar varios servos a la vez) tenemos que incluir una línea en la función setup() para informar a C++ que vamos a conectar ese objeto abstracto que todavía es servo1 a un pin físico del Arduino para controlarlo. En nuestro caso el pin 9:

servo1.attach(9);

Una vez cumplido el trámite para gobernar la posición del servo recurrimos a

servo1.write( angulo);

Donde Angulo es el valor en grados de la posición que deseamos. Fácil ¿No?

Vamos a escribir un programa que vaya barriendo un Angulo en grados y moviendo el servo a esa posición.

#include <Servo.h>                    // Incluir la librería Servo
Servo servo1;                         // Crear un objeto tipo Servo llamado servo1
int angulo = 0 ;

void setup()
    {
        servo1.attach(9) ;             // Conectar servo1 al pin 9
    }

void loop()
    {
        for(angulo  = 0; angulo  <= 180; angulo  += 1)   //incrementa angulo 1 grado
            {
                 servo1.write(angulo);
                 delay(25);
            }
        for(angulo  = 180; angulo  >=0; angulo  -=1 )    //decrementa angulo 1 grado
            {
                 servo1.write( angulo );
                 delay(25);
            }
    }

Veréis como el servo se va moviendo primero hacia adelante y luego retrocede para volver a empezar.

Vamos ahora a hacer que el valor del potenciómetro represente la posición del servo de manera que el servo se mueva siguiendo al potenciómetro. Para ello hay que entender que el valor que leamos en la puerta A0 está comprendido entre 0 y 1024, y que estos valores tienen que distribuirse entre 0 y 180º. Así que para calcular el Angulo correspondiente basta con hacer:

Img_16_1Como la experiencia me ha demostrado, que los errores haciendo este tipo proporciones tienden a infinito, voy a aprovechar para presentaros la función map()que hace exactamente eso de un modo cómodo, librándonos de los float ( aunque para aprender no os vendría mal hacer así el programa y luego usar el map()).

 angulo  = map( analogRead(A0), 0, 1024, 0, 180);

Traducido quiere decir: Haz la proporción de los valores que leas en A0, entre 0 y 1024, en un valor comprendido entre 0 y 180º y asignarle ese valor al ángulo.

Contenido solo disponible para suscriptores. ¡Accede al contenido!

       

Aqui teneis un pequeño video, mostrando el movimiento del servo

 

Resumen de la sesión

En este curso arduino hemos aprendido lo siguiente:

 

 

    • Hemos presentado los servos y hemos vista una par de programas sencillos para usarlos.
    • Hemos introducido algún concepto básico de programación orientada a objetos para que podáis utilizar las librerías.
    • Hemos definido las librerías como conjuntos de funciones y objetos que podemos utilizar sin preocuparnos de cómo funcionan internamente.
    • Las librerías son un sistema excepcional de utilizar elementos electrónicos sin tener que entrar en los detalles técnicos más o menos complicados. Esto nos abre un potencial enorme de componentes a nuestra disposición.
    • Introdujimos otra función más para nuestro arsenal: map().

 

 

 

 

 

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login

(118) Comments

  • Avatar for Charly
    • Ivan

    Hola Wladimir, en vez de indicarle directamente el ángulo que quieres que coja el servo tendrías que sumarle o restarle un número de grados al servo en función de la posición del potenciómetro para que no haga todo el movimiento en una sola instrucción sino que se mueva un poco en cada ciclo. Necesitas dos variables angulo_actual y angulo_deseado (donde guardarías la posición del potenciómetro) y compararlos. Si el deseado es mayor que el actual le sumas grados a la posición del servo y si es menor le restas. Y mientras angulo_actual y angulo_deseado sean diferentes enciendes el LED. Sería algo así:
    if (angulo_actual < angulo_deseado){ angulo_actual=angulo_actual+3; servo1.write(angulo_actual); digitalWrite (LED, HIGH); } if (angulo_actual > angulo_deseado){
    angulo_actual=angulo_actual-3;
    servo1.write(angulo_actual);
    digitalWrite (LED, HIGH);
    }

    if (angulo_deseado==angulo_actual) digitalWrite (LED,LOW);

    Y para que empiecen teniendo las dos variables el mismo valor tendrías que posicionar el servo en un ángulo determinado en el setup e igualar ambas variables.
    Un saludote.

  • Avatar for Charly

    disculap no entiendo mucho de programacion con arduino. como seria el codigo para que el led se encienda cuando se mueva el servo y se apague cuando este detenido?
    este seria el codigo para que se mueva con el potenciometro.

    #include // Incluir la librería Servo
    Servo servo1; // Crear un objeto tipo Servo llamado servo1
    int angulo = 0 ;

    void setup()
    {
    servo1.attach(9) ; // Conectar servo1 al pin 9
    }

    void loop()
    {
    angulo = map( analogRead(A0), 0, 1024, 0, 180);
    servo1.write(angulo);
    delay(250);
    }

  • Avatar for Charly
    • Admin

    Hola Nicolas, parece que tu servo es de rotacion continua y aunque nunca he usado uno hasta ahora, ceor recordar que lo que le das no indica la posicion sino la velocidad de giro. SI es asi, y el programa es el que meustras deberia pararse con:
    miservo.write(0);

  • Avatar for Charly
    • Ivan

    Hola Nicolás,con el código que tienes no puedes parar el movimiento a no ser que sea metiéndole una interrupción, porque el programa se detiene en la instrucción donde mueves el servo hasta que finaliza el movimiento.

    Lo que podrías hacer hacer es guardar el valor que recibes por el puerto serie en una variable (como en la sesión del interruptor) y dependiendo del valor de esa variable mover el servo en una u otra dirección. Pero en vez de hacer todo el movimiento en una sola instrucción moverlo un número concreto de grados en cada ciclo (como hacemos en la sesión del joystick y el servo). Entonces si se pararía si en el loop metes otra condición para que se pare el servo, y ésta se cumple.

    Si no me he explicado bien dinos y lo miramos mejor. Un saludote.

  • Avatar for Charly
    • Nicolás

    Estimado, si poseo un código que hace que al apretar un botón mi servo gire hacia la derecha indefinidamente, y que al apretar otro este gira hacia la izquierda indefinidamente, como sería el código para detener completamente el movimiento del servo?
    adjunto lo previamente descrito, Muchas gracias.

    #include
    Servo miservo;
    int estado=0;

    void setup() {
    miservo.attach(9);
    Serial.begin(9600);
    }

    void loop() {
    if(Serial.available()>0){
    estado = Serial.read();
    }
    if(estado == ‘1’){
    miservo.write(360);
    }

    else if(estado == ‘2’){

    miservo.write(-360);
    }
    }

  • Avatar for Charly
    • Ivan

    Hola Wladimir, sí podrías hacerlo. Crea otra variable angulo_anterior con el mismo valor inicial que angulo. Compárala con angulo cada ciclo y si son iguales que no se ilumine, y sí son diferentes que se encienda el LED. Después del if, vuelves a igualar los valores. Un saludote.

  • Avatar for Charly

    hola. se podria agregar un led que se encienda cuando el servo se este moviendo y que se apague cuando este detenido?

  • Avatar for Charly
    • Admin

    Si estas seguro de que no e sun problema de programacion parece un servo defectuoso

  • Avatar for Charly
    • Hector

    cada vez que le doy orden de cero el servo va al cero pero no para, se mueve lentamente hacia su limite fisico que esta en 180º. hemos puesto delay y nada sigue en movimiento no conseguimos hacer que pare.

  • Avatar for Charly
    • Admin

    Hector, no se si quieres decir que cada vez que la das la orden de cero el servo va a una posicion diferente

  • Avatar for Charly
    • Hector

    nuestro servo no tiene cero gira muy lento hacia un lado u otro hasta su final mecanico. lo hemos abierto y lo hemos realimentado por el metodo de las resistencias. alguna solucion? necesitamos el equilibrio (el cero)

  • Avatar for Charly
    • Admin

    Hola Bein, si estas seguro de que es un servo lo que usas y usas el programa que ponemos en la pagina, Si no se detiene es porque es un servo de 360º que son un poco diferentes porque la señal PWM no indica el angulo de giro sino la velocidad de rotacion continua

  • Avatar for Charly

    hola estoy amenejando un servo con arduino pero no logro q se de tenga hace giros repetitivos, que comando devo usar en la programacion de lenguaje c++ para que este solo gire 180° y se detenga.

  • Avatar for Charly
    • Admin

    Hola Pedro, necesitas una salida PWM para controlar un servo pero no tienes problemas de pines si usas un shield del tipo de este
    https://www.prometec.net/producto/servo-shield-x16/
    Porque te permite controlar hasta 16 servos sin casi quitar pines a tu arduino, con lo que no vas a tener problema con tu proyecto

  • Avatar for Charly

    Hola. ¿Se puede controlar un servo conectándolo a una salida que no sea pwm? Quiero controlar un brazo robótico de 6 servos montado en un auto de forma inalámbrica. En la dirección necesito usar pwm por lo que me va a faltar 1 salida pwm. Prefiero no tener que sacrificar un servo.

  • Avatar for Charly
    • Narciso de los palotes

    que guapo tronco

  • Avatar for Charly
    • Admin

    SI me preguntas como enviar por radio una señal que mueva un servo y si esta señalaes digital o analogica, basta con que envies un valor digital a un pin con capacidad PWM para que pòsiciones el servo

  • Avatar for Charly
    • Juan jose Boullosa Garcia

    Hola , en un receptor de radio control que mueve estos servidores ,la señal que sale para mover el servo commo se puede leer con arduino, es digital o analógica .
    Un saludo

  • Avatar for Charly
    • Admin

    Hola Jesus, Los servos de ggiro continuo no pueden ser posiconados un anguo sino que le indicas una velocidad de giro con la señal a diferencia de un servo normal en el que la señal indica el angulo que deseas. Puedes usar motores paso a paso con reductora si necesitas giro continuo y posicionamiento preciso de un angulo dado pero tendras que buscar una forma de indicar un paso por cero o algo asi

    Los motores generan mucho ruido e interferencia electronica que pueden interferir con el funcionamiento normal de tu arduino, y por eso siempre es recomendable incluir unos condensadores que reduzcan ese ruido, pero para la mayor parte de los ejemplos que hemos hecho aqui nuenca los hemos necesitado, porque la amyor parte de los shield de motores ya incorporan algun filtrado

  • Avatar for Charly
    • Jesús

    Hola:
    Una página fantástica.

    Soy bastante novato. He comprado servos Tower Pro MG 995 que son de «360º». Creo que son de rotación continua. He estado buscando documentación y no encuentro nada clarificador.
    -¿Sabe si hay alguna forma de situar en un ángulo dado un motor de estas características? (solo consigo que giren)
    -Si no se pudiera, ¿cómo se hace cuando necesitas un posicionamiento angular mayor de 180º?
    -¿Es bueno colocar en los servos condensadores y diodos rectificadores para atenuar el ruido eléctrico?

    Muchas gracias

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login