Introducción a la robótica educativa (IV)

Nota del autor

Este artículo fue inicialmente publicado en el blog de BQ, mibqyyo, y se encontraba aquí enlazado, pero actualmente ya no se encuentra disponible y, para que no desaparezca, reproduzco aquí el contenido completo.

A lo largo de esta serie de artículos hemos visto ejemplos sencillos de cómo hacer algunas cosas con la placa controladora BQ ZUM BT-328 y algunos componentes electrónicos. Ya van quedando pocas cosas que ver, y hoy quisiera mostrarte uno de los elementos más interesantes. Estoy hablando de los servomotores.

La realidad es que, como en los casos anteriores, programar y utilizar los servos es muy fácil, aunque, por supuesto, puede volverse mucho más complejo en función de lo que tu tengas en mente y quieras programar. Para controlar los servos voy a utilizar dos elementos que ya he utilizado en ejemplos anteriores, un potenciómetro y un pulsador, con los que crearé dos pequeños proyectos de ejemplo.

Controlando la posición de los servos

Una utilidad fantástica que se me ocurre rápidamente para un potenciómetro es controlar la posición de un servo, ya que ambos poseen un movimiento giratorio análogo. Así que el primer ejemplo será esto, girar un par de servos conforme a un potenciómetro.

Como siempre, lo primero es preparar las conexiones entre componentes y placa. En mi caso he conectado dos servos en los pines digitales 3 y 5 y el potenciómetro en el pin analógico A0. Cómo los servos vibran y al girar se mueven, los he fijado a una caja mediante cinta de doble cara, fácil de poner y quitar. Trucos como éste pueden facilitarte mucho la vida una vez que comiences a construir cosas más complejas, por ejemplo porque requieran de un punto de apoyo para mover cosas. A continuación te dejo una foto del montaje final.

A continuación es necesario programar el código que implemente nuestro diseño. Como vengo haciendo, te presento los bloques nuevos que utilizaré en esta ocasión:

  1. Mapear. Este bloque es muy interesante y útil para adaptar proporcionalmente rangos diferentes, por ejemplo entre un potenciómetro (cuyos valores van de 0 a 1023) y un servo (cuyos valores van de 0 a 180, por ejemplo). Se le indica una variable, previamente definida, y un rango. La función hace coincidir los primeros y últimos valores de ambos rangos (el de la variable, correspondiente al rango del potenciómetro, y el que se ha indicado manualmente, correspondiente al rango de movimiento del servo), escalando proporcionalmente los valores intermedios. El resultado final se almacena en otra variable, que ya podrá ser utilizada en un servo, pues sus valores máximo y mínimo están limitados a los máximos y mínimos de éste. 
  2. Servo. Como podrás suponer, este bloque sirve para controlar un servo, indicando en qué pin está conectado, su posición (en grados) y, opcionalmente, la pausa necesaria para que el servo alcance dicha posición. Existen multitud de tipos de servos en el mercado, pero los más habituales suelen tener un rango de movimiento entre 0 y 180 grados, como es mi caso. Recuerda que también existen servos de rotación continua, aunque esos se controlan mediante otro bloque diferente.

El código que yo he programado para este ejemplo es el que te muestro a continuación.

Lo que he querido programar es un conjunto de dos servos iguales que se muevan conforme al movimiento de un potenciómetro, con la única salvedad de que uno de ellos haga el recorrido completo de 0 a 180 grados y el otro lo haga a la mitad, de 0 a 90 grados. De esta forma puedes ver muy claramente la utilidad y forma de uso de la función mapear.

Lo primero, como siempre, es declarar las variables que voy a necesitar. Una para el valor del potenciómetro y otras dos para los valores de los servos. A continuación almaceno el valor de la posición del potenciómetro en su variable correspondiente ValorPot. Aquí es donde entra en juego la función mapear. Primero, en ValorServo1 almaceno el valor mapeado del potenciómetro entre 0 y 180 grados, todo el rango de movimiento. A continuación hago lo mismo en ValorServo2, pero, en este caso, el mapeo lo realizo únicamente entre 0 y 90 grados. Por último, utilizado ambos valores mapeados como entrada de posición de cada servo (¡No olvides indicar el pin digital correspondiente al que está conectado cada servo!).

El resultado final lo puedes ver en el siguiente vídeo:

Como puedes observar, el primero de los dos servos se mueve completamente de un lado al otro, mientras que el segundo se queda a mitad de recorrido. Mientras que el primero representa completamente el giro del potenciómetro, el segundo tan sólo lo hace a la mitad. Esto puede serte muy útil en aquellos proyectos en los que necesites un rango de movimiento muy específico.

El limpiaparabrisas

A veces puede que lo que deseas sea automatizar un movimiento de servos sin tener que controlar su posición manualmente. De esto trata este segundo ejemplo, en el que te mostraré un servo que se mueve automáticamente al pulsar un botón, a modo de parabrisas.

En la siguiente imagen puedes ver la conexión, que no difiere mucho de la anterior. El servo, como antes, está conectado en el pin digital 3 y el pulsador lo he colocado en el pin digital 10.

Como ya hemos visto muchos de los bloques disponibles para programar la placa, en este caso no será necesario introducir ninguno nuevo. Ya conoces todos los que voy a utilizar.

La idea es mantener el sistema en reposo (con el servo en 0 grados) hasta que se pulse el botón. En ese momento el servo comienza a girar entre 0 y 180 grados indefinidamente hasta que se vuelva a pulsar el botón. Entonces volverá a su posición inicial en 0 grados. Recuerda que sólo es un ejemplo de programación. Existen muchas maneras de conseguir el mismo objetivo con otros códigos diferentes.

Si lo compruebas hay una gran similitud entre este código y aquel que te mostré en el segundo artículo de la serie, cuando te hablaba sobre cómo utilizar botones con estado. La variable EstadoBoton será la encargada de almacenar el estado del pulsador. Al pulsar el botón se comprueba el valor de la variable de estado para alternar entre sus valores, si estaba a «0» se pone a «1» y viceversa. El tiempo de espera está incluido para evitar que se evalúe varias veces la misma condición mientras está pulsado el botón (¡Recuerda que todo esto se ejecuta en bucle una y otra vez de forma muy muy rápida!).

En el caso de que EstadoBoton sea «1», es decir, el botón está pulsado, coloco el servo en la posición de 180 grados y, después de vuelta a 0 grados, lo que emulará al movimiento de un parabrisas. Mientras no toque el botón el valor de la variable EstadoBoton seguirá siendo el mismo y, por lo tanto, seguirá ejecutando ese código una y otra vez.

Al pulsar el botón, el valor cambiará a «0», accediendo al apartado de lo contrario del bloque si ejecutar, en el que se coloca el servo en una posición estática en 0 grados.

El movimiento de los servos se encuentra fuera del primer si ejecutar porque, de no ser así, tan sólo se haría un único movimiento de ida y vuelta, ya que a la siguiente vez que se ejecutase ese primer si ejecutar no se cumpliría la condición de estar pulsado el botón. De esta manera evaluamos la condición cuando lo pulsamos, pero la acción la llevamos a cabo de forma independiente.

El resultado final lo puedes observar en el siguiente vídeo:

Bueno, espero que te haya resultado útil e interesante este artículo y que, con un poco más de trabajo e imaginación puedas crear tus propios proyectos, quizás más complejos y divertidos que los míos. ¡A trabajar!