Controla-el-movimiento-de-servos-con-un-potenciómetro

En la entrada anterior del curso hemos visto cómo utilizar el monitor serie para controlar el color de un LED RGB, y hoy vamos a aprender cómo controlar servos (o servo motores) con la ayuda de un potenciómetro. Con esto podremos aprender, por ejemplo, a orientar un determinado sensor para que obtenga información de una zona específica.

Para ello, veremos un par de conceptos nuevos, la lectura analógica y la función map, pero explicaremos ambas después.

Lista de materiales

    • Zum Core, placa Arduino o Compatible.
    • Servo.
    • Potenciómetro.

Conexiones eléctricas

Conectar los módulos para este proyecto es muy fácil, ya que sólo tenemos que conectar el servo a un pin con salida PWM y el potenciómetro a una entrada analógica. Puedes ver un esquema de conexión en la imagen siguiente:

zum-mini-pot

El código

Vamos a empezar por el ejemplo más sencillo para luego complicarlo un poco.

Moviendo el servo a la posición indicada por el potenciómetro

Vamos a escribir primero el código completo para posteriormente analizarlo parte por parte.

Empezamos incluyendo la librería Servo y declarando las variables de los pines:

La librería Servo es especifica para este tipo de motores. La mayoría de los servos permiten movimiento entre 0 y 180º. Si quieres conocer más sobre la librería Servo puedes consultar la página de referencia de arduino.

Función setup()

En esta función indicamos que el servo está conectado en el pin digital 10.

Función loop()

En esta función es dónde debemos realizar la tarea. Debemos seguir los siguientes pasos.

  1. Leemos el valor del potenciómetro, al ser una entrada analógica dará un valor entre 0 y 1023. Usamos la función analogRead()
  2. Transformamos el valor entre 0 y 1023 en un valor entre 0 y 180, para ello usamos la función map(). La función map convierte una variable desde el rango de origen al rango de destino, es decir, una variable que está en un intervalo A-B pasará a un intervalo C-D manteniendo la posición relativa del rango de origen al rango de destino. Podéis conocer más sobre map en la página de referencia.
  3. Comandamos al servo para que vaya a la posición obtenida entre 0 y 180.
  4. Detenemos la ejecución durante 500 ms. La razón de esto es que no queremos que el servo esté continuamente cambiando de posición, esto hace que nuestro programa sea menos reactivo, pero más estable

Este es el código:

Moviendo el servo a la posición indicada por el potenciómetro sin saltos bruscos

En el siguiente ejemplo vamos a realizar la misma tarea, pero forzando al servo a avanzar en pequeños pasos de 1 grado cada 10 milisegundos. De este modo evitamos saltos groseros resultado de movimientos bruscos del potenciómetro.

Tras la declaración inicial:

Después declaramos las variables que necesitaremos para la correcta ejecución del programa:

A continuación utilizamos la función setup para inicializar el programa:

En la función setup iniciamos la librería Serial, marcamos el pin del potenciómetro como entrada e indicamos al programa en qué pin está conectado el servo. Además, mandamos un mensaje que indica al usuario que el programa está listo para funcionar.

A continuación podemos ver la función loop al completo:

Dentro de la función loop, en primer lugar, tomamos medidas del potenciómetro y utilizamos la función map para “traducir” la lectura del potenciómetro a un ángulo, y después imprimimos en el monitor serie la información del ángulo:

La lectura analógica permite distinguir los valores comprendidos entre 0 y 5 V, al contrario que la lectura digital. Las placas ZUM y Arduino, por lo general, incorporan un conversor analógico-digital de 10 bits, por lo que el rango que podemos obtener es 0-1023. Podéis conocer más sobre analogRead en la página de referencia.

Después pasamos a modificar la posición del servo, para lo que distinguimos dos casos:

  • El valor al que se moverá el servo es mayor que el actual, por lo que tenemos que aumentar la posición:

  • El valor al que se moverá el servo es menor que el actual, por lo que tenemos que disminuir la posición:

Por último guardamos el valor de posición que tiene el servo y pausamos la ejecución del programa durante un segundo:

4 comentarios

  1. me he descargado el codigo pero cuando lo abro en arduino no hay ningun codigo??

    1. Luis Díaz

      Buenas tardes Tomas,

      Dependiendo de la versión del IDE de Arduino que tengas instalado, puede pedir que generes una carpeta con el mismo nombre del archivo a ejecutar. En ese caso, generará la carpeta de manera automática y tendrás que abrir el código que se ha generado en dicha carpeta.

      He vuelto a subir el código dentro de una carpeta para solucionar este problema. Prueba descargando de nuevo el archivo y volviendolo a abrir.

      Si no es tu caso o no has podido solucionarlo así, ¿podrías explicar de manera mas extensa cuales son los pasos que has seguido para abrir el archivo?

      Un saludo.

  2. Hola que tal Luis Diaz!

    Me podrias dar una idea o un ejemplo sobre como posicionar un servo
    digamos de forma automatica sin utilizar potenciometros,ni adc,ni pulsadores esto
    lo he hecho y funciona bien,lo hice atravez de interrupcion por timer0 es decir presiono pulsador1 cargo pos=15 centro servo,presiono pulsador2 cargo pos=7 muevo servo a min, presiono pulsador3 cargo pos=23 muevo servo a max,hasta aqui todo bien,ahora lo quiero hacer en forma automata sin intervencion de pulsadores solo software …En resumen
    lo que deseo es jugar con el,valga la palabra es decir que inicie en una posicion “x”,espere un tiempo
    vaya a la pos “y”, espere un tiempo,vaya a la posicion “z”,espere un tiempo,etc.
    intente poner algo asi dentro del while pero no,creo que no es asi por que no hace lo que yo quiero es decir va hacia la posicion max pos=23 deberia de esperar 500ms y luego avanzar a la siguiente posicion y esperar y asi sucesivamente y no lo hace se queda en pos=23 (+90grados)…es por ese motivo que pido ayuda ¿habra alguna de manera de hacer esto de forma sencilla?,¿tendre que poner limites o modificar algo? ¿que me recomendarias Luis Diaz? Cualquier aportacion gracias…

    pos=23
    delay 500
    pos=15
    delay 500
    pos=7
    delay 300

    etc…Aqui un extracto de codigo

    #int_timer0
    void Pwm()
    {
    set_timer0(150);
    cont++;

    if(cont>=200)
    {
    cont=0;
    }
    if(cont<pos)
    {
    output_high(PIN_B0);
    }
    if(cont=pos)
    {
    output_low(PIN_B0);
    }
    }

    while{

    "Aqui tengo pulsadores para cargar el valor de pos y segun ese valor
    se posiciona el servo en 0g,+90g,-90g…y funciona ok
    ahora lo que quiero hacer es que se posicione en Xangulo sin utilizar pulsadores,
    ni pots,ni adc,simplemente en forma automatica…"

    }

    mi mail: navegante74@gmail.com

    1. Luis Díaz

      Hola Marcos,

      Lo más fácil que puedes hacer es utilizar el delay simple.

      Un saludo.

Los comentarios están cerrados.