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
    • Paco

    Hola,gracias por la respuesta, creo que la solución sera alimentar el arduino un instante antes que el servo, no veo otra manera.

  • Avatar for Charly
    • Admin

    Hola paco, me suena raro. Haz una prueba sencilla, antes de hacer el attach del servo, asegurate de poner a 0 el pin que lo va a gobernar con un digitalwrite(pin, low) y me dices si mejora o no

  • Avatar for Charly
    • Paco

    Hola, te comento mi problema, estoy controlando un servo futaba 3003 de 90 a 180° con un final de carrera. Pero cuando alimento el circuito, el servo hace un movimiento indeseado fuera de ese rango, superando los 180° en ese movimiento, y solo al alimentarlo, luego vuelve a su posición correcta. Lo hace tanto si alimento el servo con el arduino como si lo hago con alimentación independiente.
    Gracias de antemano.

  • Avatar for Charly
    • Admin

    Hola carlos, puede ser una averia pero seria un poco rara. Prueba desconectarlo y luego conectarlo a algun otro pin para comprobar si el problema persiste y me comentas ¿ vale?

  • Avatar for Charly
    • Ivan

    Hola! Pues tiene que ser algún problema con el servo o el potenciómetro, porque el programa está bien seguro, lo he comprobado por si acaso

    Revisa bien las conexiones y si sigue sin funcionarte prueba a usar un programa para darle un ángulo fijo al servo sin usar un potenciómetro, así puedes ver si el problema está en el servo o en el potenciómetro. Un saludote!

  • Avatar for Charly

    Hola Admi tengo un problemilla con el servo que tengo (modelo SG90 de 9g), que cuando lo conecto utilizando el programa se me pone a girar de un lado para otro sin que le de ninguna orden
    sabes que pordia ser?
    Gracias

  • Avatar for Charly
    • Ivan

    Hola Javi, en vez fijar directamente la posición del servo al valor del potenciómetro, podrías asignarlo a una variable y sumar grados de uno en uno al servo en cada loop hasta que alcance el valor que quieres, metiéndole un delay de diez segundos cada vez que gire un grado. Un saludote.

  • Avatar for Charly
    • Javi

    Hola!

    Sabéis si hay alguna manera de mandar a un servo que gire un grado cada 10 segundos?

    Gracias de antemano un saludo!

  • Avatar for Charly
    • Ivan

    Hola Frann, sólo puedes usar los pines que tienen implementado el PWM, o sea 3, 5, 6, 9, 10 y 11. Un saludote.

  • Avatar for Charly
    • Frann Anthony

    Bueno la pregunta era sobre si cualquier pin digital se puede ser usado del arduino uno para un servomotor SG90 ,solo me queda disponible el pin 13, el 1->tx y RX<-0 los demas estan en uso de un keypad 4×4 , 2 leds y un zumbador .

  • Avatar for Charly
    • Admin

    Hola Frann,
    Es prefeerobles que postees por aqui tus problemas porque asi los demas pueden ver el problema y las posibles respuestas

  • Avatar for Charly
    • Frann Anthony

    Hola muy interesante tu tema sobre servomotores tengo una una duda que quisiera que me ayudes, pero seria mejor por alguna red social si tuvieras o correo espero tu respuesta. Gracias

  • Avatar for Charly
    • Admin

    Hola Fabiam Hay mucha oferte de servos de difernetes caracteristicas en el mercado. Prueba aqui en nuestra tienda:
    https://www.prometec.net/producto-categoria/motores/

  • Avatar for Charly

    Buenos dias, muy bueno tu artículo.

    Eh desarrollado un pequeño prototipo de simulador con los servos sg09. Funcionan muy bien.

    Mi pregunta es: existe o conoces algún modelo servo que soporte mucha mas carga, y claro, de mayor tamaño ?.

    Muchas gracias

  • Avatar for Charly
    • Admin

    Hola Ricardo, la respuesta a tu pregunta es delicada y terreno poco conocido en general. Para empezar cuando arduino dispara una interrupcion se congela el procso normal y se ejecuta la funcion asociada, por eso es importante salir pronto del esa funcion porque s etrata de una situacion excepcional en al amplio sentido de la palabra.

    En los microprocesadores se puede establecer una jeraquia de interrupciones de modo que aun dentro de una , otra de nivel superior dispare y despues vuelta a la funcion de servicio de la interrupcion previa, pero aparentemente y como norma general en Arduino todas las interrupciones se programan de igual nivel por lo que creo que si durante el servicio de una interrupcion, se dispara otra, la ultima sera ignorada (Otra buena razon para acabar lo antes posible)

    Seguramente se podra establecer algun tipo de prioridad a bajo nivel con el AVR peor lo poco que he visto por internet lo desaconseja

  • Avatar for Charly
    • Admin

    Hola Ricardo,

    Crea una variable global que se llame por ejemplo
    bool boton_pulsado = false

    Y cuando entres a la interrupcion simplemente invierte su estado, Despues haz el write al servo solo si boton_pulsado = true

    Ten cuidado con el debouncing del boton y poco mas

  • Avatar for Charly
    • Ricardo

    Hola, ya he conseguido lograr lo que proponía anteriormente, mediante interrupciones. Aunque ahora se me genera otra duda, utilizo el mega y es posible implementar hasta 6 interrupciones. Tengo entendido que al activar una interrupción se congela todo el código que no sea la interrupción, si utilizo dos interrupciones, es posible que cada interrupción congele solo una parte de código cada una?

  • Avatar for Charly
    • Ricardo

    Hola fantástica web, he leído tanto este articulo como el de interrupciones y no consigo dar con la tecla.
    Seria mover un servo en función de un potenciometro. Hasta aquí todo claro. Ahora si quiero añadir un pulsador, el cual en el momento que se pulse, detenga el servo mientras que este pulsado, independientemente que el potenciometro lo muevas o no, debería estar parado el servo, hasta que el pulsador deje de estar activo. He probado a hacerlo mediante interrupciones pero no consigo hacerlo.

    #include
    Servo servo1;
    int potenciometro =2;
    void setup() {

    pinMode (2,INPUT);
    Serial.begin(9600);
    servo1.attach(9);
    attachInterrupt (0,Boton,HIGH);

    }

    void loop() {

    int valpotenciometro = analogRead(potenciometro);
    int val = map(valpotenciometro, 0, 1023, 0 ,180);
    Serial.println(val);
    servo1.write(val);
    delay(20);
    }

    void Boton(){

    }

  • Avatar for Charly
    • Admin

    Hola Miguel,

    So servos de diferente concepcion. EL pequeño SG90 es un servo muy sencillo y barato, pensado para pequeños proyectos y aprender con el el, pero no tiene buena duracion porque su objetivo fundamental es ser barato

    El s3003 es un servo de calidad intermedia, tiene mas par , 180º de angulo y pensado para proyectos que no tengan demasiada carga pero tambine bastante mas fuerza que el anterior

    Si no tienes claro cual de los dos te interesa, probablemente te conviene el S3003

  • Avatar for Charly

    q diferencia hay entre un servomotor sg90 y un servomotor s3003

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