microcontrolador

Paso 7. Montando los bigotes

Paso 7. Montando los bigotes

     Última actualizacón: 16 noviembre 2017 a las 17:00

cartel-robotica

Muchas máquinas robotizadas dependen de una variedad de interruptores táctiles para, por ejemplo, contar objetos en una línea de producción o alinearlos durante los procesos industriales. En estos casos los interruptores ofrecen una entrada de datos que ordenan otro tipo de salida programada de datos.

En el paso anterior enseñamos a andar al robot, pero lo hacía a ciegas ya que si tropezaba con un obstáculo allí se quedaba. Ahora vamos a colocarle unos sensores que le avisen de la presencia de obstáculos en su camino, además de indicarle si dicho obstáculo se encuentra a la derecha o a la izquierda. Con esa información podremos indicarle que realice un movimiento de desvío que lo evite y así pueda proseguir hacia su objetivo.

Para ello vamos a emplear dos bumpers, nombre técnico con el que se conoce a ciertos interruptores que cierran sus contactos cuando se presiona uno de ellos. En nuestro caso, los bumpers están conformados por dos alambres de acero y tienen el aspecto de bigotes o antenas. Los llamaremos bigotes porque sirven para detectar objetos como lo hacen los bigotes de un gato. En este paso los utilizaremos solos, pero pueden ser combinados con otros sensores como veremos más adelante.

Montando los bigotes

Antes de grabar un programa para que robot se mueva en función de lo que encuentra en su camino, necesitamos montarlos y probarlos primero. Vamos a utilizar los siguientes materiales:

  • Dos alambres de acero.
  • Dos tornillos de cabeza plana de 3×15 mm.
  • Dos separadores metálicos de 3×10 mm.
  • Dos arandelas de baquelita de 3 mm.
  • Dos conectores de tres pines.
  • Dos resistencias de 220 Ω.
  • Dos resistencias de 10 Ω.
Material para el montaje de los bigotes.

Material para el montaje de los bigotes.

Material para el montaje de los bigotes.

Material para el montaje de los bigotes.

Primero debemos quitar los tornillos que unen la tarjeta Home Work con los dos separadores frontales. Colocamos un separador y una arandela de baquelita en cada uno de los tornillos.

Retirar el tornillo.

Retirar el tornillo.

Colocamos el separador y la arandela.

Colocamos el separador y la arandela.

Colocamos los tornillos sobre los agujeros de la tarjeta y atornillamos a los separadores que hay debajo, pero no debemos apretarlos completamente todavía. Enganchamos los bigotes a los tornillos y colocamos uno por encima de una de las arandelas y el otro por debajo, de tal forma que no se toquen entre sí.

Insertamos los bigotes.

Insertamos los bigotes.

Ahora podemos terminar de apretar los tornillos y colocar los conectores de tres pines:

Resultado.

Resultado.

Colocamos los conectores de tres pines.

Colocamos los conectores de tres pines.

Prueba de funcionamiento

Ahora vamos a construir el circuito eléctrico de los bigotes para añadirlo a los circuitos de zumbador y los servos que montamos en el paso anterior:

Diagrama de circuito para el montaje de los bigotes.

Diagrama de circuito para el montaje de los bigotes.

Cada bigote es una extensión mecánica de un interruptor normalmente abierto que tiene un extremo conectado a tierra. La razón de que los bigotes estén conectados a tierra (Vss) es que los agujeros en los bordes exteriores de la tarjeta están conectados a tierra. Los separadores y tornillos metálicos conectan la señal de tierra con los bigotes.

Podemos programar el módulo del microcontrolador para que detecte cuándo se presiona un bigote. Los pines o patitas de E/S conectados a cada interruptor están configurados como entradas y reciben un voltaje. Cuando los bigotes no se presionan, el voltaje que reciben es de 5 V (1 lógico). Pero si son presionados, el circuito se cierra con tierra y los pines reciben 0 V (0 lógico).

Colocamos las conexiones y resistencias como hemos visto en el diagrama anterior y ya podemos pasar a crear el programa de control:

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Montaje del circuito.

Resultado final.

Resultado final.

Programa de prueba

Este programa está diseñado para que se puedan probar los bigotes y asegurar que funcionan correctamente. Lo que hace es mostrar el estado lógico de las entradas que corresponden a los pines P7 y P5 conectados a los bigotes (IN7 e IN5).

Todos los pines de E/S son de entrada por defecto, a menos que se programe lo contrario. Por lo tanto, los pines conectados a los bigotes tendrán un “1” si el voltaje que reciben es de 5 V (cuando el bigote no está presionado), o un “0” si lo que reciben es 0 V (cuando el bigote está presionado). Vamos a utilizar el debug terminal para mostrar esos valores:

  1. ‘ Programa de prueba.  pruebabigotes.bs2
  2. ‘ Visualizar las líneas de E/S conectadas a los «bigotes»
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. DEBUG «Estado bigotes», CR,
  6. «Izquierda     derecha», CR,
  7. «_____     _____»
  8. DO
  9. DEBUG CRSRXY, 0, 3,
  10. «P5 = «, BIN1 IN5,
  11. «P7 = «, BIN1 IN7
  12. PAUSE 50
  13. LOOP

El terminal debería mostrar que que P7 y P5 tienen unos valores igual a 1. Si presionamos el bigote derecho contra el conector de tres pines hasta que haga buen contacto, deberíamos ver en el terminar: P5 = 1, P7 = 0. Si presionamos el bigote izquierdo de la misma forma, debería aparecer: P5 = 0, P7 = 1. Si presionamos ambos al mismo tiempo debería mostrar: P5 = 0, P7 = 0. Una vez que todo es correcto seguimos adelante.

Escribimos el código en el programa de edición y lo guardamos.

Escribimos el código en el programa de edición y lo guardamos.

Ejecutamos e introducimos en el robot. No presionamos ningún bigote.

Ejecutamos e introducimos en el robot. No presionamos ningún bigote.

Presionamos el bigote derecho.

Presionamos el bigote derecho.

Presionamos el bigote izquierdo.

Presionamos el bigote izquierdo.

Presionamos ambos bigotes.

Presionamos ambos bigotes.

NOTA: el comando CRSRXY es un formateador que permite ordenar la información que el programa envía al terminal. En el programa, el formateador coloca el cursor en la columna 0 y fila 3 para mostrar los datos de forma ordenada.

Otra forma de probar los bigotes

Imaginemos que tenemos que probar los bigotes cuando no disponemos de un ordenador para ver su estado en la terminal. ¿Cómo podríamos comprobar que se han montado correctamente? Una solución pasa por programar el microprocesador para que saque un valor determinado en función de cuál es la entrada que reciba. Podemos visualizarlo con un par de circuitos LED´s que se enciendan y se apaguen en función de si los bigotes están presionados o no.

Para montar este circuito necesitamos:

  • Dos resistencias de 220 Ω (bandas roja, roja y marrón).
  • Dos diodos LED.

Como siempre, antes de montar el circuito sobre la placa debemos recordar desconectar las pilas de la tarjeta y los servos. Seguiremos el siguiente esquema:

Diagrama de circuito LED para la comprobación del funcionamiento de los bigotes con LED.

Diagrama de circuito LED para la comprobación del funcionamiento de los bigotes con LED.

Prueba de funcionamiento con LEDs.

Prueba de funcionamiento con LEDs.

Prueba de funcionamiento con LEDs.

Prueba de funcionamiento con LEDs.

Una vez montado, volvemos a conectar las pilas, e introducimos el siguiente programa en el editor:

  1. ‘ Programa de prueba.  pruebabigotesconleds.bs2
  2. ‘ Visualizar las líneas de E/S conectadas a los «bigotes»
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. DEBUG «Estado bigotes», CR,
  6.       «Izquierda     derecha», CR,
  7.       «_____     _____»
  8. DO
  9.   DEBUG CRSRXY, 0, 3,
  10.   «P5 = «, BIN1 IN5,
  11.   » P7 = «, BIN1 IN7
  12.   PAUSE 50
  13. IF (IN7 = 0) THEN
  14.   HIGH 1
  15. ELSE
  16.   LOW 1
  17. ENDIF
  18. IF (IN5 = 0) THEN
  19.   HIGH 10
  20. ELSE
  21.   LOW 10
  22. ENDIF
  23. LOOP

Escribir el código en el programa de edición. Ejecutarlo e introducirlo en el robot.

Escribir el código en el programa de edición. Ejecutarlo e introducirlo en el robot.

Como vemos, lo que hemos hecho ha sido insertar dos bloques de código IF…THEN entre el comando de pausa y el comando de bucle. Los comandos IF…THEN los explicaremos un poco más tarde pero baste decir ahora que se emplean en PBASIC para tomar decisiones. La primera declaración pone P1 a nivel alto, de forma que el LED se iluminará cuando el bigote conectado a P7 esté presionado (IN7=0). La parte del ELSE hace que el LED se apague cuando el bigote no está presionado. La segunda declaración hace lo mismo para el otro bigote. Veamos cómo funciona:

Programando el robot para navegar con los bigotes

Ha llegado el momento de poner en práctica todo lo aprendido hasta ahora para lograr que el robot reaccione a la información que le facilitan los bigotes acerca de los obstáculos que puede encontrar en su camino y pueda guiarse con ella. Cuando el robot esté en movimiento y uno de sus bigotes se presione significará que ha tropezado con un obstáculo. El programa de exploración deberá comprobar esa entrada de información, decidir qué significa y, a partir de ahí, realizar la maniobra hay que ejecutar para evitar el obstáculo y dirigir al robot en otra dirección (debemos tener presente que se trata de un movimiento libre y no podremos controlar dónde acabará el recorrido).

El siguiente programa hace que el robot vaya hacia delante hasta que se encuentre con un obstáculo. En el momento en que sea detectado por los bigotes, las rutinas y subrutinas escritas en el capítulo anterior harán que el robot retroceda y gire. Después volverá a avanzar hacia delante hasta que se encuentre con otro obstáculo.

El microcontrolador que gobierna el robot tiene que ser programado para que tome decisiones cuando uno de los bigotes es presionado. El lenguaje PBASIC dispone de un comando llamado IF…THEN. La sintaxis es como sigue:

IF (condición) THEN… {ELSEIF (condición)}…{ELSE}…ENDIF

Los puntos suspensivos significan que se puede meter un trozo de código en su lugar. El comando hace que el robot ejecute el bloque de código para la primera condición que sea verdadera. Entonces, salta hasta el comando ENDIF y continúa desde ahí.

El siguiente programa muestra una forma de evaluar las entradas de datos proporcionadas por los bigotes para decidir a qué subrutina de movimiento llamar utilizando los comandos IF…THEN:

  1. ‘ Sorteo de obstaculos.  andandoconbigotes.bs2
  2. ‘ El robot utiliza los bigotes para detectar
  3. ‘ objetos y navegar en función de los mismos
  4. ‘ {$STAMP BS2}
  5. ‘ {$PBASIC 2.5}
  6. DEBUG «Programa funcionando»
  7. ‘—–[ Variables ]
  8. pulseCount        VAR          Byte
  9. ‘—–[ Inicializacion ]
  10. FREQOUT 4, 2000, 3000
  11. ‘—–[ Rutina principal ]
  12. DO
  13.   IF  (IN5 = 0) AND (IN7 = 0)  THEN
  14.     GOSUB Back_Up
  15.     GOSUB Turn_Left
  16.     GOSUB Turn_Left
  17.   ELSEIF  (IN5 = 0)  THEN
  18.     GOSUB Back_Up
  19.     GOSUB Turn_Right
  20.   ELSEIF  (IN7 = 0)  THEN
  21.     GOSUB Back_Up
  22.     GOSUB Turn_Left
  23.   ELSE
  24.     GOSUB Forward_Pulse
  25.   ENDIF
  26. LOOP
  27. ‘—–[ Subrutinas ]
  28. Forward_Pulse:
  29.   PULSOUT 13, 650
  30.   PULSOUT 12, 850
  31.   PAUSE 20
  32.   RETURN
  33. Turn_Left:
  34.   FOR pulseCount = 0 TO 20
  35.   PULSOUT 13, 650
  36.   PULSOUT 12, 650
  37.   PAUSE 20
  38.   NEXT
  39.   RETURN
  40. Turn_Right:
  41.   FOR pulseCount = 0 TO 20
  42.   PULSOUT 13, 850
  43.   PULSOUT 12, 850
  44.   PAUSE 20
  45.   NEXT
  46.   RETURN
  47. Back_Up:
  48.   FOR pulseCount = 0 TO 20
  49.   PULSOUT 13, 850
  50.   PULSOUT 12, 650
  51.   PAUSE 20
  52.   NEXT
  53.   RETURN

Escribir el código en el programa de edición. Ejecutarlo e introducirlo en el robot.

Escribir el código en el programa de edición. Ejecutarlo e introducirlo en el robot.

Escribir el código en el programa de edición. Ejecutarlo e introducirlo en el robot.

Escribir el código en el programa de edición. Ejecutarlo e introducirlo en el robot.

El comando IF…THEN en el programa principal comprueba el estado de los bigotes. Si los dos bigotes están presionados (IN5 = 0, IN7 = 0), el robot realizará un giro en “U” llamando a la subrutina Back_Up seguida de la subrutina Turn_Left dos veces (lo que supone un giro de 180o).

Si el bigote izquierdo es el único que está presionado (IN5 = 0), el programa ejecutará la subrutina Back_Up seguida de la subrutina Turn_Right para retroceder y girar a la derecha 90o. Por el contrario, si el bigote presionado es el derecho (IN7 = 0), el programa ejecutará la subrutina Back_Up seguida de la subrutina Turn_Left para retroceder y girar a la izquierda 90o. La única posibilidad que no está resuelta en el programa es cuando los dos bigotes no están presionados (IN5 = 1, IN7 = 1) en cuyo caso el comando ELSE llama a la subrutina Forward_Pulse y envía un pulso para que el robot avance en línea recta al no haber obstáculos.

Esta subrutina tiene un detalle que hemos resaltar:

  1. Forward_Pulse:
  2.   PULSOUT 13, 650
  3.   PULSOUT 12, 850
  4.   PAUSE 20
  5.   RETURN

Sólo envía un pulso y después devuelve el control al programa principal. Esto es importante porque permite al robot comprobar sus bigotes entre cada pulso que le hace avanzar (esto lo hace gracias al comando ENDIF). Significa que el robot comprueba si hay obstáculos alrededor de 40 veces por segundo mientras avanza hacia delante: cada pulso hacia delante hace que el robot avance medio centímetro por lo que es una buena idea enviar sólo un pulso para volver a comprobar los bigotes. Dado que el comando IF…THEN está dentro de un bucle DO…LOOP, cada vez que el programa realiza un pulso hacia delante entra en el bucle que envía el programa arriba hasta el comando DO. ¿Qué sucede entonces? Que el comando IF…THEN vuelve a comprobar los bigotes de nuevo y así sucesivamente. Si no lo hiciéramos así, cuando el robot entrara en la subrutina Forward_Pulse ya no volvería a comprobarlos.

Veamos el resultado de nuestros esfuerzos:

Publicado por José Luis Moreno en ROBÓTICA, 3 comentarios
Paso 6. Programando los movimientos del robot

Paso 6. Programando los movimientos del robot

     Última actualizacón: 16 noviembre 2017 a las 13:40

En esta anotación aprenderemos a programar las maniobras fundamentales del robot: hacia delante, atrás, giros y rotaciones. Es fundamental que comprendamos bien estas maniobras y sus técnicas de programación porque las utilizaremos de ahora en adelante, aunque ahora el robot andará “a ciegas” porque aún no hemos instalado los sensores que le permitan informarse acerca del entorno que lo rodea. Nuestra tarea en los próximos pasos será instalar estos dispositivos que permitirán a nuestro robot esquivar obstáculos o seguir un camino marcado en el suelo.

Como parte indispensable de este paso, también vamos a aprender a poner a punto y calibrar la navegación del robot para que se mueva en línea recta, haga giros precisos y podamos hacer cálculos de distancias. Al final hay un vídeo donde se muestran en la práctica los mismos pasos que iremos dando.

En la imagen inferior vemos los diferentes movimientos que puede hacer el robot (como ya indicamos en pasos anteriores, debemos recordar que cuando el robot se mueve hacia delante su rueda derecha gira en el sentido de las agujas del reloj, mientras que la izquierda lo hace en sentido contrario):

Movimiento hacia delante

Con el programa que indicamos a continuación el robot avanzará en línea recta durante tres segundos.

Recordemos que el argumento Duración del comando PULSOUT controla la velocidad y la dirección de giro de los servos. Los argumentos StartValue y EndValue del bucle FOR…NEXT controlan por su parte el número de pulsos que se envían. Dado que cada pulso tiene la misma duración, el argumento EndValue también controla el tiempo que funcionan los servos.

  1. ‘ Programa de movimiento.  Avancetressegundos.bs2
  2. ‘ El robot avanza hacia delante durante tres segundos
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. Counter VAR Word
  6. FREQOUT 4, 2000, 3000                ‘señal de inicio/reset
  7. FOR counter = 1 TO 122                 ‘marcha hacia delante durante 3 s
  8.                 PULSOUT 13, 650
  9.                 PULSOUT 12, 850
  10.                 PAUSE 20
  11. NEXT
  12. END

Controlando la distancia y la velocidad

Si cambiamos por ejemplo el valor EndValue del bucle FOR…NEXT de 122 a 61, haremos que el robot se desplace hacia delante durante la mitad de tiempo, y que recorra, por tanto, la mitad de la distancia.

Hagamos la comprobación:

Ahora podemos repetir lo mismo pero cambiando el valor EndValue a 244. ¿Qué ocurre?

Los cambios que hemos hecho están relacionados con la distancia que recorre el robot, pero también podemos modificar su velocidad. Por ejemplo, si ajustamos el parámetro Duración de PULSOUT cerca de 650 o 850, los servos girarán a su máxima velocidad; mientras que si se aproximan a 750, haremos que se muevan más lentos.

Modificamos el programa de la siguiente forma:

PULSOUT 13, 720

PULSOUT 12, 780

Mover el robot hacia atrás, rotarlo y pivotarlo

Todo lo que tenemos que hacer para conseguir otros movimientos del robot es utilizar diferentes combinaciones del parámetro Duración del comando PULSOUT. Por ejemplo, estas dos instrucciones hacen que el robot vaya hacia atrás:

PULSOUT 13, 850

PULSOUT 12, 650

Estas dos para que el robot gire a la izquierda:

PULSOUT 13, 650

PULSOUT 12, 650

Y éstas para que lo haga a la derecha:

PULSOUT 13, 850

PULSOUT 12, 850

Podemos combinar estos comandos para el robot vaya en diferentes direcciones como muestra el ejemplo del siguiente programa:

  1. ‘ Programa de movimiento.  Delanteizquierdaderechaatras.bs2
  2. ‘ Hacer que el robot realice los cuatro movimientos básicos
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. Counter VAR Word
  6. FREQOUT 4, 2000, 3000                ‘señal de inicio/reset
  7. FOR counter = 1 TO 122                ‘marcha hacia delante durante 3s
  8.                 PULSOUT 13, 650
  9.                 PULSOUT 12, 850
  10.                 PAUSE 20
  11. NEXT
  12. PAUSE 200                                     ‘espera
  13. FOR counter = 1 TO 24                 ‘rotación izquierda ¼ de vuelta
  14.                 PULSOUT 13, 650
  15.                 PULSOUT 12, 650
  16.                 PAUSE 20
  17. NEXT
  18. PAUSE 200                                    ‘espera
  19. FOR counter = 1 TO 24                ‘rotación derecha ¼ de vuelta
  20.                 PULSOUT 13, 850
  21.                 PULSOUT 12, 850
  22.                 PAUSE 20
  23. NEXT
  24. PAUSE 200                                   ‘espera
  25. FOR counter = 1 TO 122             ‘retroceso
  26.                 PULSOUT 13, 850
  27.                 PULSOUT 12, 650
  28.                 PAUSE 20
  29. NEXT
  30. END

También podemos hacer que el robot pivote sobre una rueda. Para ello basta con que sólo gire una rueda mientras la otra permanece parada. Por ejemplo, si se quiere que la rueda izquierda permanezca parada y la derecha gire hacia delante para que el robot pivote, se deberán utilizar las siguientes líneas de código:

PULSOUT 13, 750

PULSOUT 12, 650

Si por el contrario se quiere que pivote hacia delante y a la derecha, simplemente se detiene la rueda derecha y hacemos que la rueda izquierda gire hacia delante:

PULSOUT 13, 850

PULSOUT 12, 750

Hacia atrás y la derecha:

PULSOUT 13, 650

PULSOUT 12, 750

Hacia atrás y a la izquierda:

PULSOUT 13, 750

PULSOUT 12, 850

Retocando las maniobras básicas

Más abajo veremos un vídeo con todas estas maniobras realizadas en la práctica y comprobamos que, a pesar de que el robot está programado para avanzar en línea recta, es frecuente que se vaya desviando ligeramente hacia uno de los lados. Vamos a corregir este desajuste mediante el software, para lo cual deberemos modificar el programa Avancetressegundos.bs2 para que en vez de 3 segundos se mueva durante 10, tiempo necesario para comprobar si se desvía o no. Esta modificación se hace cambiando el valor de EndValue en el comando FOR Counter de 122 a 407:

  1. ‘ Programa de movimiento.  Avancediezsegundos.bs2
  2. ‘ El robot avanza hacia delante durante diez segundos
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. Counter VAR Word
  6. FREQOUT 4, 2000, 3000                  ‘señal de inicio/reset
  7. FOR counter = 1 TO 407                  ‘giro hacia delante durante 10 s
  8.                 PULSOUT 13, 650             ‘servo izquierdo máxima velocidad
  9.                 PULSOUT 12, 850             ‘servo derecho máxima velocidad
  10.                 PAUSE 20
  11. NEXT
  12. END

Pongamos por caso que el robot se desvía hacia la izquierda. Esto puede pasar por dos motivos: o bien la rueda izquierda gira más lenta, o es la rueda derecha la que lo hace más rápido. Como el robot está programado para que cada servo gire a la máxima velocidad, lo más lógico será pensar que la rueda derecha debería girar un poco más despacio.

Ya hemos visto que la velocidad de los servos está determinada por el argumento Duración del comando PULSOUT. Cuanto más se acerque este valor a 750, más lento girará el servo. Esto significa que hay que cambiar el valor 850 del comando PULSOUT 12 a un valor más cercano a 750. Si el robot no se desvía demasiado, con un valor de 837 será suficiente. Si por el contrario el grado de desvío es grande, habrá que poner como mínimo un valor de 810. Como vemos, será necesario hacer varias pruebas modificando este argumento hasta lograr que el robot siga una línea completamente recta.

En nuestro caso, ha sido necesario un valor de 800 para conseguir un movimiento rectilíneo.

Al igual que hemos hecho para el avance, tendremos que hacer los mismos ajustes para el movimiento hacia atrás.

También es posible regular los giros del robot mediante el software. El tiempo que dura el movimiento de las ruedas del robot es lo que determina el ángulo de giro. Como ya hemos visto que el comando que controla el tiempo de giro en el programa es el bucle FOR … NEXT, lo que tenemos que hacer es modificar el argumento EndValue para que gire más o menos según queramos.

En el programa Delanteizquierdaderechaatras.bs2 introdujimos una serie de órdenes para que el robot realizase distintos giros, por lo que si hay cualquier tipo de desviación deberemos modificar el contador del bucle FOR counter = 1 TO 24 y disminuir el tiempo de giro (probamos primero con 23, 22 etc.) Si sigue sin girar los 90o exactos, modificaremos el comando PULSOUT a un valor más cercano a 750, como hicimos para que fuese recto. Repetiremos la acción hasta que gire los 90o exactos.

Cálculo de distancias

Es frecuente que en las competiciones que se organizan los robots tengan que seguir un recorrido desde un punto inicial hasta un destino situado a cierta distancia, para luego regresar al punto de partida. Vamos a aprender a calcular distancias, para lo cual aplicamos la fórmula general de la velocidad:

Tiempo = distancia / velocidad

Distancia = velocidad x tiempo

Lo que traducido al funcionamiento de nuestro robot sería:

Tiempo de movimiento del servo = distancia recorrida / velocidad del robot

Para poder aplicar esta sencilla fórmula debemos calcular en primer lugar la velocidad del robot. La forma más fácil de hacerlo es poner una regla a su lado y ver qué distancia recorre en un tiempo dado (un segundo por ejemplo). Conociendo los centímetros que ha recorrido y el tiempo en segundos empleado en ello, podremos determinar la velocidad del robot en centímetros por segundo. Emplearemos para ello el siguiente programa:

  1. ‘ Programa de movimiento.  Avanceunsegundo.bs2
  2. ‘ El robot avanza hacia delante durante un segundo
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. Counter VAR Word
  6. FREQOUT 4, 2000, 3000                ‘señal de inicio/reset
  7. FOR counter = 1 TO 41                  ‘marcha hacia delante durante 1s
  8.                 PULSOUT 13, 650
  9.                 PULSOUT 12, 800
  10.                 PAUSE 20
  11. NEXT
  12. END

Este programa controla el movimiento del robot durante un segundo por lo que si ha recorrido 23 cm durante su ejecución, la velocidad será de 23 cm/s (es conveniente recordar que en un paso anterior aprendimos que los servos tardan 24,6 milisegundos (0,0246 segundos) en completar un ciclo de ejecución del bucle FOR … NEXT, por lo que el microcontrolador envía 40,65 pulsos cada segundo a los servos (1/0,0246 pulsos por segundo).

Una vez aclarado este concepto, podemos hacer que el robot se desplace en cualquier dirección una distancia concreta. Por ejemplo, sabiendo la velocidad que alcanza, podemos calcular el tiempo que necesitaría el robot para recorrer una distancia de 51 centímetros:

Tiempo = 51 cm / 23 cm/s = 2,22 s

Cuando tenemos este dato, basta calcular los pulsos que han de enviarse a los servos para que el robot recorra esa distancia, teniendo en cuenta que para que el robot se mueva durante un segundo son necesarios 40,65 pulsos:

Pulsos = 2,22 s x 40,65 pulsos/s = 90,24 pulsos = 90 pulsos

90 es el valor que tendremos que usar en el argumento EndValue del bucle FOR … NEXT

En cualquier caso tenemos que tener presente que estas mediciones no son completamente exactas. No hemos tenido en cuenta, por ejemplo, que el robot necesita un determinado número de pulsos para alcanzar la máxima velocidad, ni tampoco la distancia que recorre hasta que se detiene por completo o el hecho de que los servos girarán más despacio cuando las baterías pierdan potencia.

Maniobras de aceleración y desaceleración

Lo que pretendemos es que el robot acelere y desacelere de forma gradual. De esta forma conseguiremos que los servos y las baterías duren más y que el arranque y la parada no sean tan bruscos.

La clave para acelerar es ajustar el parámetro Duración del comando PULSOUT. Gracias al bucle FOR … NEXT podemos hacer que el robot acelere:

PulseCount VAR Word

FOR pulseCount = 1 TO 100

PULSOUT 13, 750 – pulseCount

PULSOUT 12, 750 + pulseCount

PAUSE 20

NEXT

Cada vez que se ejecuta el bucle FOR … NEXT la variable pulseCount se incrementa en 1. A medida que el valor de pulseCount es mayor, la velocidad de los servos también. La primera vez que se ejecuta el bucle, la variable pulseCount vale 1, que es lo mismo que usar los comandos PULSOUT 13, 749 y PULSOUT 12, 751. La segunda vez, la variable valdrá 2, y así, a la centésima vez que hemos ejecutaado el bucle, la variable pulseCount valdrá 100 que es lo mismo que usar los comandos PULSOUT 13, 650 y PULSOUT 12, 850 (máxima velocidad hacia delante)

Si por el contrario hacemos que el bucle FOR … NEXT reduzca la variable pulseCount, el robot desacelerará hasta pararse. Hagamos las pruebas:

  1. ‘ Programa de movimiento.  Arranqueyparo.bs2
  2. ‘ El robot acelera y luego decelera hasta pararse
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. pulseCount VAR Word                     ‘contador del bucle FOR … NEXT
  6. FREQOUT 4, 2000, 3000                ‘señal de inicio/reset
  7.                                                           ‘aceleración gradual
  8. FOR pulseCount = 1 TO 100           ‘bucle aceleración de 100 pulsos
  9.                 PULSOUT 13, 750 – pulseCount
  10.                 PULSOUT 12, 747 + pulseCount
  11.                 PAUSE 20
  12. NEXT
  13.                                                           ‘avance constante de 75 pulsos
  14. FOR pulseCount = 1 TO 75
  15.                 PULSOUT 13, 650
  16.                 PULSOUT 12, 800
  17.                 PAUSE 20
  18. NEXT
  19.                                                          ‘desaceleración hasta detenerse
  20. FOR pulseCount = 100 TO 1          ‘bucle desaceleración de 100 pulsos
  21.                 PULSOUT 13, 750 – pulseCount
  22.                 PULSOUT 12, 747 + pulseCount
  23.                 PAUSE 20
  24. NEXT
  25. END

Facilitar los movimientos con subrutinas

En los siguientes pasos de la construcción del robot vamos a programarlo para que sea capaz de realizar maniobras con el fin de evitar obstáculos. Una de las formas más eficientes de hacerlo es realizando maniobras pre-programadas mediante el empleo de subrutinas. Ahora vamos a aprender a crear y utilizar esta herramienta.

Una subrutina es una secuencia de instrucciones que se repite en diversas ocasiones a lo largo del programa principal. Para no tener que reescribirla e insertarla cada vez que se necesite, lo que hacemos es ponerla como un programa independiente al que se “llama” cada vez que sea preciso.

Hay dos partes dentro de una subrutina en PBASIC. La primera es la “llamada a la subrutina”, es decir, la instrucción que hace que una vez que el programa llegue allí, se ejecute la parte de código que se contiene dentro de la subrutina. La otra parte es la propia subrutina en sí, la parte reutilizable del código. La subrutina comienza cuando se referencia con GOSUB su nombre (también llamado etiqueta) y finaliza con el comando RETURN, que devuelve el control a la siguiente instrucción después de GOSUB. El código que hay entre la etiqueta del nombre de la subrutina y RETURN es lo que se ejecutará en cada llamada a esa subrutina:

DO

DEBUG “Antes de la subrutina”, CR

PAUSE 1000

GOSUB Mi_subrutina

DEBUG “Después de la subrutina”, CR

PAUSE 1000

LOOP

Mi_subrutina:

DEBUG “Subrutina en ejecución”, CR

PAUSE 1000

RETURN

Este trozo de código nos muestra una llamada a una subrutina y la propia subrutina. Como hemos dicho, la llamada a la subrutina se realiza con el comando GOSUB y el nombre de la subrutina, en nuestro caso “Mi_subrutina” (ojo con los espacios en blanco). Una vez se inicia la subrutina se ejecuta línea a línea hasta encontrar el comando RETURN que obliga a salir de la subrutina y continuar ejecutando el programa en el punto en que se dejó.

Vamos a usar esta herramienta para manejar los movimientos del robot:

  1. ‘ Programa de movimiento con subrutinas.  Movimientoconsubrutina.bs2
  2. ‘ El robot realiza los movimientos básicos mediante subrutinas
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. Counter VAR Word
  6. FREQOUT 4, 2000, 3000                ‘señal de inicio/reset
  7. GOSUB Delante
  8. GOSUB Izquierda
  9. GOSUB Derecha
  10. GOSUB Atras
  11. END
  12.                                                          ‘movimiento hacia delante
  13. Delante:
  14.                 FOR counter = 1 TO 64
  15.                                 PULSOUT 13, 650
  16.                                 PULSOUT 12, 800
  17.                                 PAUSE 20
  18.                 NEXT
  19.                 PAUSE 200
  20.                 RETURN
  21.                                                          ‘giro a la izquierda
  22. Izquierda:
  23.                 FOR counter = 1 TO 24
  24.                                PULSOUT 13, 650
  25.                                PULSOUT 12, 650
  26.                                PAUSE 20
  27.                 NEXT
  28.                 PAUSE 200
  29.                 RETURN
  30.                                                          ‘giro a la derecha
  31. Derecha:
  32.                 FOR counter = 1 TO 24
  33.                                PULSOUT 13, 850
  34.                                PULSOUT 12, 850
  35.                                PAUSE 20
  36.                 NEXT
  37.                 PAUSE 200
  38.                 RETURN
  39.                                                          ‘movimiento hacia atrás
  40. Atras:
  41.                 FOR counter = 1 TO 64
  42.                                PULSOUT 13, 840
  43.                                PULSOUT 12, 650
  44.                                PAUSE 20
  45.                 NEXT
  46.                 RETURN

Publicado por José Luis Moreno en ROBÓTICA, 1 comentario
Pasos 5.1, 5.2 y 5.3 Diversas comprobaciones

Pasos 5.1, 5.2 y 5.3 Diversas comprobaciones

     Última actualizacón: 15 noviembre 2017 a las 22:55

En este nuevo paso de la construcción del robot, vamos a comprobar que las conexiones eléctricas entre la tarjeta y los servos son correctas. Es preciso que nos aseguremos de que el servo de la derecha gira cuando recibe señales procedentes de P13 y que el servo de la izquierda hace lo propio cuando recibe señales de P12 según el montaje realizado en el paso anterior.

En la siguiente imagen vemos nuestro robot con las indicaciones de posición que se seguirán de ahora en adelante para evitar confusiones:

5.1 Comprobando el funcionamiento de las ruedas

Vamos a ejecutar un sencillo programa para probar el servo conectado a la rueda derecha. Hará que la rueda gire en la dirección de las agujas del reloj durante 3 segundos, parará durante un segundo y, después, girará en sentido contrario durante otros 3 segundos.

  1. ‘ Programa de prueba de servos.  Pruebaservoderecho.bs2
  2. ‘ El servo derecho gira en sentido horario 3s, se para 1s
  3. ‘ y vuelve a girar 3s en sentido antihorario
  4. ‘ {$STAMP BS2}
  5. ‘ {$PBASIC 2.5}
  6. Counter VAR Word
  7. FREQOUT 4, 2000, 3000                ‘señal de inicio/reset
  8. FOR counter = 1 TO 122                 ‘giro horario durante 3s
  9.                 PULSOUT 13, 650
  10.                 PAUSE 20
  11. NEXT
  12. FOR counter = 1 TO 40                   ‘parada 1s
  13.                 PULSOUT 13, 750
  14.                 PAUSE 20
  15. NEXT
  16. FOR counter = 1 TO 122                  ‘giro antihorario durante 3s
  17.                 PULSOUT 13, 850
  18.                 PAUSE 20
  19. NEXT
  20. END

Para ponerlo en marcha, cargaremos el programa en el editor de Basic Stamp y lo introduciremos en la tarjeta del robot como hemos visto en pasos anteriores. Acto seguido colocamos el interruptor de energía en la posición 2 (que alimenta los servos) y ejecutamos el programa.

Los mismos pasos daremos con el servo de la rueda izquierda:

  1. ‘ Programa de prueba de servos.  Pruebaservoderecho.bs2
  2. ‘ El servo derecho gira en sentido horario 3s, se para 1s
  3. ‘ y vuelve a girar 3s en sentido antihorario
  4. ‘ {$STAMP BS2}
  5. ‘ {$PBASIC 2.5}
  6. Counter VAR Word
  7. FREQOUT 4, 2000, 3000                ‘señal de inicio/reset
  8. FOR counter = 1 TO 122                 ‘giro horario durante 3s
  9.                 PULSOUT 12, 650
  10.                 PAUSE 20
  11. NEXT
  12. FOR counter = 1 TO 40                   ‘parada 1s
  13.                 PULSOUT 12, 750
  14.                 PAUSE 20
  15. NEXT
  16. FOR counter = 1 TO 122                  ‘giro antihorario durante 3s
  17.                 PULSOUT 12, 850
  18.                 PAUSE 20
  19. NEXT
  20. END

Vemos cómo la única diferencia entre estos dos programas es que hemos sustituido el punto de enganche del servo derecho (P13) por el servo izquierdo (P12) en el segundo programa.

Ahora vamos a comprobar como el robot se mueve según las indicaciones de la programación: la rueda derecha girará en sentido horario durante tres segundos, se detendrá un segundo, y volverá a girar en sentido antihorario otros 3 segundos (lo mismo sucederá con la rueda izquierda).

5.2 Detector acústico de baja tensión y reinicio

Cuando el suministro de voltaje eléctrico cae por debajo del nivel que el dispositivo necesita para funcionar correctamente se produce un apagón parcial. La tarjeta se protege a sí misma de esta situación haciendo que el procesador y los microchips de memoria permanezcan en estado de reposo hasta que el suministro de energía vuelva a niveles normales.

Una bajada de tensión en Vin por debajo de 5,2 V provoca un voltaje inferior a 4,3 V en el regulador interno de la tarjeta, valor insuficiente que origina una anomalía y que provoca, como hemos señalado, que se ponga en marcha un mecanismo de autoprotección del sistema en el que tanto el procesador como la memoria pasan a un estado de reposo que detiene la ejecución de instrucciones. Cuando el voltaje vuelve a niveles adecuados, la tarjeta se pone en funcionamiento de nuevo pero no donde había quedado ejecutándose el programa, sino desde el principio del mismo. Es lo mismo que sucede cuando pulsamos el botón de reinicio del sistema.

Cuando las baterías están bajas, es posible que estas bajadas de tensión hagan reiniciarse al robot cuando menos lo esperamos, haciendo que tome direcciones erróneas, dé vueltas sobre sí mismo etc.

Esto hace que un programa que indique la posibilidad de reinicio del robot sea muy útil (de esta forma sabemos claramente cuál ha sido la causa del funcionamiento incorrecto de nuestro robot). Una forma para avisar de un posible reinicio es incluir una señal inconfundible al comienzo de todos los programas del robot. La señal se produce cada vez que se conecta el suministro de energía y cuando se produce un reinicio debido a una bajada de tensión.

En este ejercicio vamos a colocar un dispositivo llamado zumbador piezoeléctrico que se puede usar para generar diferentes tonos en función de la frecuencia de las señales que se envíen desde la tarjeta.

El programa que vamos a cargar a continuación produce un pitido a través del zumbador. Utiliza el comando FREQOUT para enviar las señales de la frecuencia que se deseemos por una patita de la tarjeta. Su sintaxis es como sigue:

FREQOUT Pin, duración, frecuencia1, {Frecuencia2

Un ejemplo sería FREQOUT 4, 2000, 3000: envía una señal de 3000 hercios (3 kHz) durante 2000 ms (2 segundos) por el pin 4.

En este punto debemos tener presente que la frecuencia es una magnitud que mide el número de repeticiones por unidad de tiempo de cualquier fenómeno o suceso periódico. Nuestro zumbador funciona gracias a la piezoelectricidad: es un fenómeno presentado por determinados cristales que al ser sometidos a tensiones mecánicas adquieren una polarización eléctrica en su masa, apareciendo una diferencia de potencial y cargas eléctricas en su superficie. Este fenómeno también se presenta a la inversa, esto es, se deforman bajo la acción de fuerzas internas al ser sometidos a un campo eléctrico. El efecto piezoeléctrico es normalmente reversible: al dejar de someter los cristales a un voltaje exterior o campo eléctrico, recuperan su forma.

De esta forma, cuando aplicamos cambios de voltaje a gran velocidad hacemos que el cristal piezoeléctrico cambie de forma rápidamente. Esto provoca una vibración. Los objetos que vibran hacen que el aire que los rodea vibre también, y esta vibración es lo que nuestros oídos detectan como sonido y tonos.

La frecuencia se mide en hercios (Hz). Un hercio representa un ciclo por cada segundo, entendiendo ciclo como la repetición de un suceso. De esta forma, un kHz representa mil ciclos por segundo.

Más abajo se muestra el símbolo del zumbador y el esquema de conexión del terminal positivo del zumbador a la patita P4 de E/S.

Para el montaje tomamos el zumbador y lo colocamos sobre la tarjeta. Vemos que una pegatina indica cuál de las dos patas es de signo positivo así que solo tenemos que presionar y listo. Para dejar más espacio para el resto de componentes, y dado que este elemento quedará fijo de forma permanente, es mejor colocarlo lo más esquinado posible.

Una vez colocado, sólo tenemos que realizar la conexión de los cables, uno conectando el polo positivo del zumbador a P4 (cable azul) y el otro al conector de energía (Vss)

Programa ejemplo

El siguiente programa emite un pitido del zumbador al iniciarse su ejecución y luego envía mensajes visualizadores de DEBUG cada medio segundo dentro de un bucle infinito. Se puede simular una bajada de tensión presionando el botón de reinicio o bien desconectando la batería del robot; entonces el programa se reiniciará, emitiendo un pitido de nuevo. Cada vez que se produce un pitido sabemos que el programa se ha iniciado desde el principio.

  1. ‘ Programa de reinicio.  Indicadorinicioreinicio.bs2
  2. ‘ Prueba del altavoz piezoeléctrico.
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. DEBUG CLS, “Beep!!!”                         ‘visualiza el mensaje mientras suena
  6. FREQOUT 4, 2000, 3000                      ‘señal sonora
  7. DO                                                         ‘bucle DO…LOOP
  8. DEBUG CR, “Esperando el reinicio”      ‘visualiza el mensaje
  9. PAUSE 5000                                          ‘cada medio Segundo
  10. LOOP                                                     ‘hasta que se reinicie el sistema

El programa comienza mostrando el mensaje (en la pantalla del ordenador) “Beep!!!” cuando se inicia su ejecución. Inmediatamente envía una señal de 3 kHz al zumbador durante 2 segundos. Como la tarjeta ejecuta muy rápidamente las instrucciones dará la sensación de que el mensaje se muestra al mismo tiempo que el zumbador comienza a pitar.

Cuando cesa el pitido, el programa entra en un bucle infinito mostrando una y otra vez el mensaje “Esperando el reinicio”. Cada vez que se produzca un reinicio, bien porque se aprieta el botón o porque se desconectan las baterías o pierden tensión, el programa se reiniciará.

De ahora en adelante vamos a usar este programa cada vez que escribamos otro. Lo consideraremos parte de la rutina de inicialización de cada programa.

5.3 Probando el control de velocidad del robot

En este paso de comprobación vamos a dibujar las curvas que relacionan la velocidad de giro de los servos con la amplitud de los pulsos que se aplican desde la tarjeta Home Work. Este gráfico nos resultará muy útil ya que cuando queramos obtener una velocidad concreta de las ruedas del robot sólo tendremos que consultar éste para saber la amplitud del pulso que se debe aplicar a cada una. Para ello vamos a utilizar el panel de transmisión del terminal DEBUG del programa de edición para enviar valores al programa de ejecución de la tarjeta.

Empleo del comando DEBUGIN

Ya hemos visto en anteriores ocasiones que gracias al comando DEBUG se visualizan los mensajes en la pantalla del ordenador que manda la tarjeta al ejecutar un programa determinado. El terminal DEBUG del programa de edición Basic Stamp también tiene una ventana de transmisión que nos permite enviar información al microcontrolador mientras se está ejecutando un programa. Esto lo hacemos a través del comando DEBUGIN, que toma el valor que introducimos con el teclado y lo envía al programa que está ejecutando la tarjeta para que una o más variables queden fijadas por dicho valor. Es decir, con este comando se introducen valores de variables que se usan en los programas de la tarjeta Home Work.

En el siguiente programa de ejemplo, utilizaremos la variable pulseWidth (amplitud de pulso) para almacenar los valores que el comando DEBUGIN recibe. Evidentemente, tendremos que declarar previamente esta variable al programa

pulseWidth        VAR       Word

Ahora, el comando DEBUGIN captura los valores decimales que introducimos con el teclado a través del panel de transmisión y los almacena en la variable pulseWidth:

DEBUGIN            DEC        pulseWidth

De esta forma podemos programar el microcontrolador para que use este valor. En el siguiente ejemplo se utiliza la variable pulseWidth como el argumento Duración del comando PULSOUT:

PULSOUT 12, pulseWidth

Programa ejemplo

Este programa nos va a permitir establecer el argumento Duración del comando PULSOUT introduciéndolo a través del panel de transmisión del terminal DEBUG del programa de edición.

  1. ‘ Programa de control de velocidad. Pruebavelocidadservo.bs2
  2. ‘ Introducir la amplitud del pulso y contar el número de vueltas
  3. ‘ que gira la rueda durante 6 segundos. Multiplicando por 10
  4. ‘ este valor conocemos las revoluciones por minuto (RPM)
  5. ‘ {$STAMP BS2}
  6. ‘ {$PBASIC 2.5}
  7. counter                       VAR       Word
  8. pulseWidth                 VAR       Word
  9. pulseWidthComp       VAR       Word
  10. FREQOUT 4, 2000, 3000                ‘ señal de inicio/reinicio
  11. DO
  12.                 DEBUG “Indicar la amplitud del pulso:”
  13.                 DEBUGIN DEC pulseWidth
  14.                 pulseWidthComp = 1500 – pulseWidth
  15.                 FOR counter = 1 TO 244
  16.                                PULSOUT 12, pulseWidth
  17.                                PULSOUT 13, pulseWidthComp
  18.                                PAUSE 20
  19.                 NEXT
  20. LOOP

Nota importante: cuando en un programa se definen variables, tanto el tipo como la dirección hay que colocarlas alineadas para su correcta ejecución.

Pasos a seguir

  1. Haremos una pequeña marca en la rueda del robot para tener un punto de referencia.
  2. Colocamos el interruptor de encendido del robot en la posición “2” (que envía energía a los servos).
  3. Ejecutar el programa Pruebavelocidadservo.bs2
  4. Introducir el valor 650 en el panel de transmisión del terminal DEBUG y pulsar ENTER
  5. Contar las vueltas que da la rueda izquierda (el servo habrá girado durante 6 segundos en el sentido de las agujas del reloj, por lo que si multiplicamos el número de vueltas por 10 obtendremos el número de RPM).
  6. Escribimos el valor en la tabla que reproducimos más abajo junto a la celda de 1300 ms.
  7. Introducir el valor 655.
  8. Contar las vueltas que da la rueda.
  9. Multiplicar el valor por 10 y escribirlo junto al valor 1310 ms de la tabla.
  10. Ir incrementando los valores de 5 en 5 (0,01 ms) hasta llegar a 850 (1700 ms).
  11. Repetir el proceso para el otro servo (para ello tendremos que modificar el comando PULSOUT del programa de forma que los pulsos se envíen a P12).

¿Cómo trabaja el programa?

Se declaran tres variables: counter para el bucle FOR…NEXT, pulseWidth para los comandos DEBUGIN y PULSOUT, y pulseWidthComp, que almacena un valor que se usa en un segundo comando PULSOUT.

counter                         VAR       Word

pulseWidth                  VAR       Word

pulseWidthComp       VAR       Word

El commando FREQOUT (como vimos en el paso 5.2) lo utilizamos para indicar mediante un pitido del zumbador que el programa se ha iniciado.

El resto del programa se incluye dentro del bucle DO…LOOP lo que indica que se ejecutará una y otra vez. El programa le pide al operador del terminal DEBUG (nosotros) que introduzcamos un valor decimal que determinará la duración del pulso que se va a guardar en la variable pulseWidth. Para lograr una medición del tiempo más exacta se envían dos comandos PULSOUT cuyos argumentos Duración sumarán 1500 entre los dos

pulseWidthComp = 1500 – pulseWidth

Así se consigue que el bucle FOR…NEXT tarde siempre el mismo tiempo en ejecutarse independientemente del valor del argumento Duración que hayamos introducido y, por tanto, que las mediciones de las RPM que hagamos sean más exactas. Este bucle FOR…NEXT envía pulsos al servo izquierdo (P12) durante 6 segundos. El valor de la variable pulseWidthComp se envía al servo derecho (P13), haciendo que gire en la dirección contraria.

En el paso 4 vimos cómo se calculaba el tiempo: recordemos que el argumento Duración del comando PULSOUT se expresa en unidades de 2 millonésimas de segundo por lo que un valor de 650 envía pulsos de 1,3 ms de duración (a lo que es lo mismo 1300 ms).

Con los datos que vayamos obtenido vamos a completar la siguiente tabla para obtener nuestra propia curva de transferencia (debemos tener en cuenta que nuestro programa de ejemplo controla la rueda izquierda con los valores que introducimos. La rueda derecha gira en dirección contraria).

Una vez completada la tabla para la rueda izquierda, debemos modificar el comando PULSOUT para enviar el pulso a la rueda derecha, cambiando los parámetros como se indica

PULSOUT 13, pulseWidth

PULSOUT 12, pulseWidthComp

realizando a continuación las mismas mediciones.

Debemos tener en cuenta que los valores positivos de RPM se dan cuando la rueda gira en el sentido de las agujas del reloj, mientras que los valores negativos indican un giro de las ruedas en sentido antihorario. Recordar igualmente que, dada la disposición de los servos, para que el robot ande hacia adelante la rueda derecha tendrá que girar en sentido de las agujas del reloj, mientras que la izquierda en sentido antihorario.

Publicado por José Luis Moreno en ROBÓTICA, 1 comentario
Paso 5. El montaje

Paso 5. El montaje

     Última actualizacón: 14 noviembre 2017 a las 16:52

Bien, es hora de ponernos manos a la obra. Tras aprender a programar y hacer las debidas comprobaciones con los componentes esenciales, ha llegado el momento de montar el robot en sí mismo.

Describiremos paso a paso las operaciones necesarias para montar la estructura, las ruedas del robot y hacer las primeras conexiones. Se trata de un trabajo muy sencillo que, en mi caso, no me ha llevado más de una hora (y eso que he ido tomando las fotografías que ilustran cada explicación).

Las herramientas que vamos a emplear son el destornillador que acompaña el kit de montaje, unos alicates de punta y las pinzas de relojero que ya he utilizado con anterioridad.

Montaje del chasis

Para montar el chasis vamos a necesitar los siguientes componentes:

  • Chasis metálico.
  • 4 tubos metálicos (llamados separadores) de 20 mm.
  • 4 tornillos de 10 mm.
  • 1 goma que recubre el hueco interior por donde pasarán los cables.

Lo primero que haremos será introducir a presión la goma con la que vamos a recubrir el hueco situado en el centro del chasis ya que será por donde pasarán los diferentes cables. Acto seguido atornillaremos los cuatro tubos metálicos que actuarán como separadores entre el chasis en sí mismo y la tarjeta Home Work. Los puntos de fijación están situados en cada esquina:

Ya tenemos la estructura básica. Lo siguiente que haremos será colocar los servos en su lugar (recordemos que actúan como los motores de las ruedas). Para ello, primero debemos retirar las aspas quitando el tornillo central (recomiendo sujetar las aspas mientras se realiza esta operación para evitar forzar el servo). Las aspas salen fácilmente aplicando una leve presión. Una vez hecho lo anterior, guardaremos los dos tornillos porque serán necesarios más adelante.

Montaje de los servos en el chasis

Para montar los servos necesitaremos los siguientes elementos:

  • 8 tornillos de 6 mm.
  • 8 tuercas.

De nuevo la operación es muy sencilla. Elegiremos uno de los laterales del chasis e insertaremos el servo correspondiente como se muestra en la imagen inferior, de forma que el rotor sobresalga por el exterior (aquí irá montada la rueda). Acto seguido atornillaremos cada uno de los cuatro tornillos en su lugar junto con sus tuercas correspondientes:

Haremos lo mismo en el otro lateral:

Vemos como en este caso el potenciómetro queda «mirando» al interior del chasis con un acceso bastante difícil debido a la posición del portapilas (como nosotros hemos centrado los servos con anterioridad no resulta relevante). Sin embargo, esto se hace así porque el robot gana en maniobrabilidad. En cualquier caso, no hay problema en situar el potenciómetro hacia afuera aunque habría que hacer unos pequeños ajustes en la programación para corregir esta ubicación.

Una vez montados ambos servos, procederemos a introducir los cables por el hueco interior donde antes pusimos la goma protectora:

Instalación del portapilas

Como ya hemos explicado, el robot utiliza cuatro baterías para el movimiento de los servos, que constituyen la mayor parte de su peso y va situado detrás de los dos servos. Este elemento de plástico ya cuenta con dos orificios donde se introducirán los tornillos. Para su sujeción necesitamos los siguientes elementos:

  • 2 tornillos de 10 mm. con la cabeza plana.
  • 2 tuercas.

De nuevo el montaje es muy sencillo. Colocamos el portapilas, introducimos los dos tornillos y los sujetamos con las tuercas. Es importante colocarlo de forma que el cable quede lo más cerca posible del hueco central para evitar enredos:

Una vez colocados los servos y el portapilas, e introducidos los cables por el hueco central, esta es la vista de la parte superior del chasis:

Como detalle decir que he colocado dos etiquetas de colores para diferenciar el servo izquierdo y el derecho ya que será necesario tener claro cuál es cuál a la hora de hacer la conexión en la tarjeta Home Work y programar el movimiento del robot:

Montaje de las ruedas

Para montar las ruedas vamos a necesitar los siguientes elementos:

  • 2 ruedas de plástico.
  • 2 gomas elásticas (actúan como neumáticos).
  • 1 bola de plástico (es la rueda trasera).
  • 2 tornillos (los que reservamos al retirar las aspas de los servos).
  • 1 chaveta metálica.

Lo primero que vamos a hacer es colocar la rueda trasera. Se trata de una bola de plástico con un agujero que la atraviesa. La chaveta metálica funcionará como un eje y permitirá que el robot tome cualquier dirección con el movimiento de las dos ruedas motrices delanteras.

Para ello, colocaremos la bola entre los dos agujeros en la parte trasera del chasis e introduciremos la chaveta metálica:

Acto seguido doblaremos los dos extremos para impedir que se salga de su lugar (más adelante podremos recortarlos ya que, aunque no impide el libre movimiento de la rueda, resulta algo antiestético).

Antes de posicionar las ruedas en los servos, tenemos que estirar las gomas elásticas y ajustarlas a la superficie exterior de cada rueda:

La colocación de las ruedas delanteras es muy sencilla ya que cada una tiene un hueco que encaja con el eje exterior de los servos. Presionamos levemente y empleamos los tornillos que antes retenían las aspas para sujetar las ruedas. Estas son las imágenes que muestran el robot con todas sus ruedas y el cableado asomando por el agujero central:

El último paso consistirá en montar la tarjeta Home Work de control sobre el chasis. Para ello emplearemos cuatro tornillos de cabeza redonda de 10 mm. y los fijaremos en los tubos metálicos que actúan como separadores:

Podemos darnos cuenta de que los cables tienen una longitud excesiva por lo que es recomendable utilizar una presilla o cualquier otro medio de recogerlos entre el chasis y la parte inferior de la tarjeta, dejando solo el tramo necesario para realizar las conexiones. Esto evitará que sobresalgan y se enreden con las ruedas:

Acto seguido conectamos el cable del portapilas en su lugar:

Y por último, conectamos los cables de los servos a los conectores adecuados de la tarjeta Home Work como hemos hecho en los pasos anteriores a este montaje:

Muy bien, ya tenemos listo nuestro robot para comenzar a instalar diversos sensores y realizar las pruebas.

Publicado por José Luis Moreno en ROBÓTICA, 2 comentarios
Paso 4. Los motores del robot

Paso 4. Los motores del robot

     Última actualizacón: 30 mayo 2017 a las 18:37

Poco a poco vamos entrando en materia.  En este paso vamos a conectar, ajustar y probar los motores del robot.  Para ello necesitaremos comprender ciertos comandos del lenguaje PBASIC y unas técnicas de programación que determinarán la dirección, velocidad y duración del movimiento de los servomotores (llamados también servos).

Los motores del Boe-Bot

Los servos de rotación continua que vamos a emplear son los que aparecen en las siguientes imágenes:

Los servomotores estándar se diferencian de los de giro continuo en que éstos últimos pueden girar de forma continua en los dos sentidos, mientras que los primeros sólo giran 270o.  Los servos estándar se han diseñado para recibir señales electrónicas que les dicen qué posición concreta mantener.  En cambio, las señales que reciben los servos de rotación continua les dicen qué velocidad y dirección deben seguir, lo que los convierten en ideales para controlar ruedas y poleas (aquí dejo un tutorial para convertir un servo estándar en uno de rotación continua como una buena manera de conocer mejor el funcionamiento de ambos).

Primera tarea: medición del tiempo y control de repeticiones

Para controlar la velocidad de un servo y su dirección se requiere un programa que haga que el microcontrolador envíe el mismo mensaje de forma continua (las señales deben repetirse unas 50 veces por segundo para que el servo mantenga su velocidad y dirección).  Para lograrlo, vamos a escribir varios programas de ejemplo en PBASIC que muestran cómo repetir la misma señal una y otra vez y controlar la duración de la misma.

En el paso 2, y con más detalle en el paso 3, aprendimos el funcionamiento del comando PAUSE que indica al microcontrolador que debe esperar un tiempo determinado antes de ejecutar el siguiente comando.  Como recordarán, el formato es:

PAUSE duración

El valor del parámetro duración establece el tiempo de espera en milisegundos (por lo tanto, si queremos que el microcontrolador espere un segundo deberemos utilizar como valor 1000).

Vamos a utilizar un sencillo programa para comprobar otras funciones de este comando:

  1. ‘ Tercer programa de prácticas del robot Boe-Bot.  Tercerprograma.bs2
  2. ‘ Mostrar cómo el comando PAUSE permite visualizar mensajes
  3. ‘ controlando el tiempo transcurrido
  4. ‘ {$STAMP BS2}
  5. ‘ {$PBASIC 2.5}
  6. DEBUG «Inicio…»
  7. PAUSE 1000
  8. DEBUG CR, “Ha transcurrido un segundo”
  9. PAUSE 2000
  10. DEBUG CR, “Han transcurrido tres segundos”
  11. DEBUG CR, “Fin”
  12. END

Es conveniente que tengamos en cuenta que el valor máximo de duración para el comando PAUSE es 65535 (poco más de un minuto y cinco segundos).

Uno de los motivos por los que son tan útiles un ordenador y un microcontrolador es que pueden hacer una y otra vez las mismas cosas aburridas sin quejarse.  Vamos a ver el ejemplo de un programa que hace que se repita la misma operación constantemente. Para ello emplearemos los comandos DO y LOOP:

  1. ‘ Cuarto programa de prácticas del robot Boe-Bot.  Cuartoprograma.bs2
  2. ‘ Visualizar un mensaje por segundo
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. DO
  6.                 DEBUG “Hola!”, CR
  7.                 PAUSE 1000
  8. LOOP

Con la estructura del lenguaje PBASIC formada por DO … LOOP se puede repetir de forma indefinida la secuencia de instrucciones que se encuentra entre dichos comandos.

También se puede modificar el programa de forma que parte de él se ejecute una sola vez y otra parte se ejecute varias veces:

  1. DEBUG “Hola!”
  2. DO
  3.                 DEBUG “!”
  4.                 PAUSE 1000
  5. LOOP

Segunda tarea: comando de control del servo

Antes de explicar los comandos que controlan los servos, necesitamos saber qué es un diagrama de tiempos porque lo emplearemos a menudo para representar la relación entre los niveles alto (HIGH — Vdd) y bajo (LOW — Vss) y el tiempo de duración de cada uno de esos estados (ya vimos la utilidad de los comandos HIGH y LOW en el paso anterior).

En el diagrama, el tiempo se representa de forma creciente de izquierda a derecha:

Este diagrama muestra un tren de pulsos de un segundo de duración en el que se envía un nivel alto durante medio segundo, y uno bajo durante otro medio segundo.  Esto puede representar, por ejemplo, el encendido de un led durante medio segundo y su apagado durante otro medio segundo de forma reiterada (la línea de puntos de la derecha indica que la señal se repite continuamente).

Los niveles lógicos altos y bajos que genere el programa de control de giro de los servos deben durar una cantidad muy concreta de tiempo.  Esto es así porque el circuito electrónico que gobierna los servos mide la cantidad de tiempo que una señal permanece alta y la usa como si se tratase de una instrucción para girar.  Para controlar con precisión el giro, el tiempo que esas señales permanecen altas tiene que ser mucho más exacto de lo que se puede conseguir utilizando los comandos HIGH y PAUSE.  En el caso del comando PAUSE, como hemos visto, sólo se puede controlar su parámetro duración con pasos de 1 ms.

Sin embargo, para una mayor precisión hay un comando diferente: PULSOUT, que proporciona señales de nivel alto durante periodos de tiempo muy pequeños (en este caso, su parámetro duración se expresa en valores de unidades de 2 millonésimas de segundo). Se escribe:

PULSOUT pin, duración

Tercera tarea: conexión de los servos

Vamos a montar los servos y los conectaremos a unas baterías de alimentación así como a la tarjeta. Emplearemos circuitos LED para controlar las señales que el microcontrolador envíe a los servos para determinar su movimiento ya que de esta forma las señales también iluminarán los LED.

En primer lugar, debemos asegurarnos que el interruptor de energía de la tarjeta está en la posición “0” de apagado.

La siguiente imagen muestra el lugar donde se conectan los servos. Pueden observar como entre los conectores X4 y X5 hay tres pines con una leyenda en la parte superior (Vdd) y otra en la inferior (Vin). Dos de estos pines aparecen conectados por un puente. En la imagen vemos cómo el puente está colocado en la posición superior (Vdd) así que tendremos que cambiarlo a la posición (Vin) ya que vamos a utilizar un bloque de 4 pilas como fuente de energía (los servos consumen bastante intensidad por lo que es recomendable utilizar pilas potentes y recargables):

Extraerlo es muy sencillo, basta utilizar unas pinzas para sacar el puente de su lugar. Luego lo insertaremos de nuevo a presión en la posición inferior:

Bien, una vez solucionado el tema de la alimentación, ya podemos conectar los servos como se muestra en las siguientes imágenes:

Importante: tengamos en cuenta que de los servos parten tres cables: el blanco se conecta a cualquiera de los conectores P12 o P13, el rojo a la toma Vin y el negro a la toma de tierra (Vss).

Como hemos indicado al inicio, montaremos el siguiente circuito LED para visualizar las señales que se envíen a los servos y comprobar que todo funciona correctamente:

Cuarta tarea: ajustando los servos

Vamos a ejecutar un programa que enviará una señal a los servos que les obligará a permanecer parados. Como los servos, por lo general, no vienen ajustados de fábrica, cuando se aplica la señal de “paro” es posible que mantengan un ligero movimiento que hay que eliminar (esta operación recibe el nombre de “centrar” los servos). Para realizar el ajuste emplearemos un destornillador con punta de estrella.

El siguiente diagrama muestra la señal que se enviará para calibrar los servos. Es la señal de centrado y consiste en una serie de pulsos de 1,5 ms de duración, con una pausa entre cada uno de ellos de 20 ms, que generaremos con el comando PULSOUT que ya hemos visto:

Los servos están preparados para permanecer detenidos cuando se les envía un pulso de 1,5 ms, así que daremos al comando PULSOUT un parámetro duración con valor 750 (recordemos que 1,5 milisegundos son 0,0015 segundos, por lo que al expresarse el valor del parámetro duración en unidades de 2 millonésimas de segundo, la cifra que tendremos que darle tendrá que ser el cociente entre ambas:

Es conveniente ajustar los servos de uno en uno ya que así podremos escuchar si el que estamos probando se está moviendo ligeramente. El siguiente programa va a ajustar el servo conectado a P12, cuando terminemos la operación, bastará cambiar a P13 para repetir el procedimiento con el otro servo:

  1. ‘ Programa de centrado de servo. Centradoservo.bs2
  2. ‘ Este programa envía un pulso de 1,5 ms al servo conectado a
  3. ‘ P12 para el centrado manual
  4. ‘ {$STAMP BS2}
  5. ‘ {$PBASIC 2.5}
  6. DO
  7. PULSOUT 12, 750
  8. PAUSE 20
  9. LOOP

Antes de cargar y ejecutar el programa deberemos encender la placa colocando el interruptor en la posición “2”, que es la que entrega energía a los servos. Una vez ejecutado el programa comprobaremos que el LED de monitorización conectado a P12 se enciende, lo que indica que se están transmitiendo pulsos al servo. Si el servo no está bien ajustado (lo más probable), su aspa comenzará a girar y oiremos el motor interno haciendo ruido.

Es posible que el servo no gire en absoluto. Esto puede significar que, o bien está ajustado de fábrica, o que está dañado o defectuoso. Más tarde realizaremos una comprobación antes de que instalemos los servos en el chasis del robot para verificar que el servo funciona correctamente.

Bien, esto es lo que debemos hacer:

Acto seguido repetiremos el proceso con el servo conectado a P13.

Quinta tarea: registrando valores y contando

Vamos a aprender qué son las variables y a utilizarlas en los programas para almacenar valores. Todos los programas que vamos a necesitar a partir de ahora utilizarán en gran medida las variables. La utilidad más importante cuando se guardan variables es que permite que el programa las use para contar. De esta forma podremos controlar el número de veces que se repiten las cosas.

Antes de que podamos usar una variable en lenguaje PBASIC, debemos nombrarla y establecer su tamaño, esto es lo que se llama “declarar” la variable:

Nombrevariable VAR tamaño

Podemos declarar cuatro tamaños diferentes:

Bit ― 0 a 1

Nib ― 0 a 15

Byte ― 0 a 255

Word ― 0 a 65535

Una vez declarada una variable, podemos inicializarla, es decir, podemos asignarle un valor inicial (si no lo hacemos el programa comenzará automáticamente almacenando el número 0 que es el valor por defecto):

valor = 500

otro_valor = 2000

El símblo «=» es un operador. Podemos utilizar distintos para realizar operaciones matemáticas y como por ejemplo, multiplicar «*»:

valor = 10 * valor

Programa de ejemplo: variablesymatemáticassimples.bs2

Este programa muestra la forma de declarar variables, inicializarlas y realizar algunas operaciones con ellas:

  1. ‘ Programa de declaración de variables. Variablesymatemáticassimples.bs2
  2. ‘ Declara variables que se emplean en diversos cálculos matemáticos
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. valor VAR Word ‘Declaración de variables
  6. otrovalor VAR Word
  7. valor = 500 ‘Inicialización de variables
  8. otrovalor = 2000
  9. DEBUG ? valor ‘Visualiza valores
  10. DEBUG ? otrovalor
  11. valor = 10 * otrovalor ‘Cálculo matemático
  12. DEBUG ? valor ‘Visualiza resultados
  13. DEBUG ? otrovalor
  14. END

Conteo y control de repeticiones

La manera más adecuada de controlar el número de veces que se ejecuta un fragmento de código de programa es utilizando el bucle FOR…NEXT. Su sintaxis es la que sigue:

FOR contador = valorinicial TO valorfinal {STEP valorincremento}…NEXT

Los puntos suspensivos se sustituyen por el comando o comandos que deseamos repetir. Debemos declarar previamente las variables «contador» (esta variable la podemos llamar como queramos), «valorinicial» y «valorfinal» que pueden ser tanto números como variables o, incluso, una expresión (que veremos más adelante). Cuando veamos algo entre llaves { } en una descripción de la sintaxis de una instrucción, significa que es un parámetro opcional.

Programa de ejemplo: contarhastadiez.bs2

  1. ‘ Programa de cuenta. contarhastadiez.bs2
  2. ‘ Empleo de una variable en un bucle FOR…NEXT
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. contador VAR Word
  6. FOR contador = 1 TO 10
  7. DEBUG ? contador
  8. PAUSE 500
  9. NEXT
  10. DEBUG CR, «He acabado!»
  11. END

Como vemos, lo que hace el programa es contar hasta diez. Si modificamos los valores inicial y final, por ejemplo, colocando como valor inicial un 9 y valor final un 1, lo que veremos será una cuenta atrás ya que el valor inicial es mayor que el final.

Del mismo modo, el parámetro STEP hace que el bucle cuente por pasos: en vez de números seguidos, podemos hacer que cuente de dos en dos, o de cien en cien según el valor que le demos:

  1. FOR contador = 100 TO 1 STEP 10
  2. DEBUG ? contador
  3. PAUSE 500
  4. NEXT

Sexta tarea: comprobando los servos

Antes de montar los servos en el robot debemos comprobar que responden correctamente. Para ello vamos a ejecutar un programa que enviará señales de giro a los servos en diferentes direcciones y a diferentes velocidades.

Control de la velocidad y la dirección

El circuito electrónico que gobierna el servo está preparado para que cuando reciba impulsos de 1,3 ms de duración cada 20 ms haga girar el eje del motor en el sentido de las agujas del reloj y a la máxima velocidad (oscila entre 50 y 60 revoluciones por minuto, RPM). Cuando se aumenta la duración del impulso de 1,3 ms a 1,5 ms la velocidad de giro decrece hasta que se para el motor. Cuando se aplica al servo un impulso de 1,7 ms de duración cada 20 ms, el eje del motor gira en sentido antihorario y a máxima velocidad. Cuando se reduce la duración del impulso a 1,5 ms decrece la velocidad de giro hasta detenerse.

Un esquema general de los impulsos necesarios para el movimiento del servo sería el siguiente:

Veamos los programas que controlan el giro:

Programa de ejemplo: servoP12sentidohorario.bs2

  1. ‘ Programa de control de servo. ServoP12sentidohorario.bs2
  2. ‘ Activa el servo P12 a velocidad máxima en sentido horario
  3. ‘ {$STAMP BS2}
  4. ‘ {$PBASIC 2.5}
  5. DO
  6. PULSOUT 12, 650
  7. PAUSE 20
  8. LOOP

Basta con realizar cambios en los parámetros de duración para hacer que los servos giren en un sentido o en el otro, o hacer que uno de ellos lo haga en sentido horario y el otro en el sentido antihorario. El que cada servo gire en diferente dirección es de gran importancia ya que una vez montados, ambos servos se encuentran enfrentados, por lo que si giran en el mismo sentido el robot no dejará de dar vueltas sobre su propio eje. Para que el robot avance en la misma dirección, cada uno de los servos deberá girar en un sentido distinto y a la misma velocidad:

Programa de ejemplo: P12horarioP13antihorario.bs2

  1. ‘ Programa de control de los servos. P12horarioP13antihorario.bs2
  2. ‘ Mueve el servo P12 a velocidad máxima en sentido horario
  3. ‘ Mueve el servo P13 a velocidad máxima en sentido antihorario
  4. ‘ {$STAMP BS2}
  5. ‘ {$PBASIC 2.5}
  6. DO
  7. PULSOUT 12, 650
  8. PULSOUT 13, 850
  9. PAUSE 20
  10. LOOP

Control del tiempo que gira el servo

Ya conocemos la forma de controlar la velocidad de giro y la dirección del servo, lo único que nos falta es determinar el tiempo que permanece girando. Para ello emplearemos el bucle FOR…NEXT:

  1. FOR contador = 1 TO 100
  2. PULSOUT 13, 850
  3. PAUSE 20
  4. NEXT

Para calcular el tiempo de forma adecuada necesitamos saber la cantidad exacta de tiempo que tarda el código en hacer que el servo gire. Cada vez que se recorre el bucle, el comando PULSOUT tarda 1,7 ms en ejecutarse, el comando PAUSE tarda 20 ms y el bucle en sí mismo tarda unos 1,3 ms en ejecutarse. Por lo tanto, un ciclo completo se completa en 23 ms o, lo que es lo mismo, en 0,023 segundos.

Ya que según el ejemplo anterior el bucle se ejecuta 100 veces, tardará 2,3 segundos en llevarse a cabo.

Programa de ejemplo: Controltiempofuncionamientoservo.bs2

  1. ‘ Programa de control de los servos. Controltiempofuncionamientoservo.bs2
  2. ‘ Mueve el servo P13 durante 2,3 s a velocidad máxima en sentido
  3. ‘ antihorario. A continuación, mueve el servo P12 el doble de tiempo
  4. ‘ {$STAMP BS2}
  5. ‘ {$PBASIC 2.5}
  6. contador VAR Byte
  7. FOR contador = 1 TO 100
  8. PULSOUT 13, 850
  9. PAUSE 20
  10. NEXT
  11. FOR contador = 1 TO 100
  12. PULSOUT 12, 850
  13. PAUSE 20
  14. NEXT
  15. END

Veamos un vídeo que resume lo hecho hasta ahora:

Publicado por José Luis Moreno en ROBÓTICA, 2 comentarios