E10_com_protocoder

¡Bienvenido!

En esta entrada vamos a aprender a programar y controlar un PrintBot desde un terminal con la ayuda de Protocoder.

Protocoder es una herramienta de prototipado de aplicaciones móviles, permite crear interfaces y programas rápidamente. Protocoder está desarrollado por Victor Díaz, y puedes encontrar información y descargar Protocoder aquí.

Utilizaremos Protocoder como interfaz, que emplearemos para comunicarnos con la placa Zum BT-328 mediante Bluetooth, y podremos mover el PrintBot Evolution de manera libre o utilizar cada uno de los modos automáticos: sigue líneas, sigue luz y evita obstáculos.

Para controlar el PrintBot Evolution utilizaremos dos programas:

  1.  Código Protocoder: almacenará la interfaz gráfica y las funciones encargadas de enviar datos a la placa Zum a través del Bluetooth del terminal.
  2.  Código Zum BT-328: almacenará la programación del PrintBot Evolution, como por ejemplo, los modos de funcionamiento o la comunicación Bluetooth.

Podréis descargar ambos códigos al final de esta entrada. Recuerda que para ejecutar el código de Protocoder deberás tener instalado Protocoder en tu terminal (puedes descargarlo desde aquí).

Código Protocoder

Para ver y modificar el código de Protocoder, en primer lugar, accede a la aplicación Protocoder desde tu terminal e introduce la dirección IP que aparece en la parte inferior de la pantalla del navegador web de tu ordenador.

ip_protocoderDescarga el código al final de esta entrada y pasa el archivo printbot_evolution_protocoder.proto a tu terminal. En tu terminal, con un explorador de archivos, dirígete a la carpeta donde hayas guardado el archivo, generalmente descargas, pulsa sobre el código de Protocoder y aparecerá un dialogo, escoge abrir con Protocoder. Se abrirá una ventana y escoge la opción install. Ya podrás utilizar y modificar el código.
E10_com_protocoder

Una vez que hayas importado el archivo .proto, verás el proyecto en la pestaña del navegador MY PROJECTS. Pulsa sobre el icono y verás el código. Dentro del código podemos distinguir varías partes:

  1. Crear botón de texto: crea un botón con un texto dentro de él, es útil para dar más información sobre el uso que se tiene del botón. Para crearlos utilizamos un código como este:

    Dentro del código, con var btnSiguelinas estamos declarando el botón, tendremos que dar un nombre distinto a cada botón para que no haya conflictos. Después, con ui.addButton decimos que la variable btnSiguelineas será un botón. Entre paréntesis escribimos, por orden, el texto que aparecerá en el botón, la posición en X e Y, el ancho y el alto del botón. Después indicamos la función que se accionará al pulsar el botón, en este caso, envía por Bluetooth la palabra siguelinas.
  2. Crear botón con imagen

    Con var btn180 estamos declarando el botón, pero no es como el anterior, en este caso, utilizamos una imagen en vez de un texto. Después, con ui.addImageButton decimos que la variable btn180 será un botón de imagen. Entre paréntesis escribimos, por orden, la posición en X e Y, el ancho, el alto del botón y el nombre de la imagen que queremos que aparezca en el botón. Después indicamos la función que se accionará al pulsar el botón, en este caso, envía por Bluetooth la palabra 180.

    Para añadir una imagen o cualquier otro archivo, basta con arrastrar el archivo desde el explorador de archivos de tu ordenador al cuadro inferior derecha. Recuerda que cuanto más sencillo sea el nombre que tenga, más fácil será introducirlo en el código sin errores.

    archivos

  3. Crear botones para el Dashboard: Para incluirlos lo hacemos del mismo modo que los botones para el dispositivo, solo que en vez de utilizar el prefijo ui, utilizamos el prefijo dashboard. Por defecto, el Dashboard no aparecerá, pero si quieres que así sea, modifica la línea dashboard.show(false); por dashboard.show(true);.
  4. Funciones para conexión y desconexión de Bluetooth: Se trata de las incluidas dentro de las variables btnConectar y btnDesconectar. Además, creamos una variable con el nombre btClient, que utilizaremos para “interactuar” a través del Bluetooth.
    1. Conectar: Para conectar, en primer lugar creamos un botón con el texto “Conectar Bluetooth” y dentro de la función que se activará al pulsar dicho botón, incluimos la conexión a Bluetooth.

      Dentro de la función, además de conectarnos a Bluetooth, decimos que la variable bluetoothOn -que utilizamos como “señal” de conexión/desconexión al bluetooth- se le asigna el valor 1 y cambiamos la transparencia del botón a 0, es decir, completamente transparente. Además, incluimos algunas animaciones, como jump y hacemos que el dispositivo vibre cuando se ha conectado.

    2. Desconectar: Para desconectar, en primer lugar, creamos un botón con el texto “Desconectar” y dentro de la función que se activará al pulsar dicho botón, incluimos la desconexión a Bluetooth.

      Dentro de la función, además de desconectarnos a Bluetooth, decimos que la variable bluetoothOn -que utilizamos como “señal” de conexión/desconexión al Bluetooth- se le asigna el valor0 y cambiamos la transparencia del botón a 255, es decir, opaco.

  5. Función para enviar y recibir datos por Bluetooth: La función para la transmisión de datos por Bluetooth es:

    Esta función no tiene ningún botón, ya que se llamará a esta función cada vez que pulsemos sobre un botón, a excepción de los de conexión y desconexión por Bluetooth. Para enviar datos por Bluetooth utilizamos la orden btClient.send(“=”+str+”+”);. Esta función envía, por ejemplo, para mover el coche hacia delante: =avanzar+. En este caso, se ha realizado la codificación de esta manera, pero puedes probar con otro tipo de codificación. Se utilizan los caracteres = y + como delimitadores del inicio y final de la transmisión.

    1. Envío de datos por Bluetooth: Para enviar datos a través del Bluetooth utilizamos la función send() con un texto entre comillas dobles, por ejemplo, si queremos enviar la palabra retroceder utilizaríamos: send(“retroceder”);

Código Arduino

Para ver y modificar el código de Arduino, descarga el paquete al final de esta entrada y pulsa sobre el archivo printbot_evolution_arduino.ino. Si no tienes instalado el IDE de Arduino o otro IDE con el que puedas leer el archivo, puedes descargarlo visitando el curso de programación para makers con Arduino y Protocoder, ver diferentes IDEs y descargar tu favorito. Además, podrás aprender más sobre Arduino y Protocoder.

Una vez con el archivo abierto, dentro del código podemos distinguir varias partes:

  1. Declaración de variables e inclusión de librerías: Declaramos las distintas variables que utilizaremos durante el programa:

    Dentro de las variables utilizaremos algunas para decir a Arduino en qué pines están conectados las vitaminas, y otras, como los delays, para modificar la ejecución del programa. Si los giros no se realizan correctamente o quieres modificarlos para que giren otros ángulos, puedes modificar las variables giro_180, giro_90, giro_45 y giro_30.
  2. Setup: En la función setup, una de las que estamos obligados a utilizar en Arduino junto a loop inicializaremos el programa y los componentes que lo forman. El código de la función setupes:

    Dentro de esta función, iniciamos el puerto serie a una velocidad de 19200 bauds/s, que es la velocidad a la que funciona el módulo Bluetooth de la placa ZUM BT-328. A continuación decimos donde está conectado cada servo, paramos los servos de movimiento y llevamos el servo que lleva el sensor Bat, de ultrasonidos, a su posición central. Por último, con la orden pinMode(pin,mode) establecemos los diferentes pines como entradas, INPUT, o salida, OUTPUT, según corresponda.
  3. Loop: Dentro de la función loop, la otra función de Arduino que estamos obligados a utilizar, tratamos la recepción de datos:

    Dentro de esta función, vemos la orden if (Serial.available() >0) que traducido a lenguaje “humano” sería: Si hay datos en el puerto serie, entonces haz las ordenes siguientes. En este caso, las ordenes son llamar a la función readFromAndroid();. Esta función se encarga de leer los datos enviados desde la aplicación de Protocoder.

    La otra orden que aparece en loop es writeData();. Esta función se encarga de entrar en los diferentes modos de control, tanto los manuales como los externos, una vez que se han leído los datos de la función anterior.

  4. readFromAndroid();:

    En vez de esta función, podríamos haber utilizado la función readString(); pero la lectura se realiza más despacio, por lo que las órdenes que enviamos desde el programa de Protocoder en nuestro terminal hasta el PrintBot Evolution llegarían con retraso.

  5. writeData();: Esta función es la encargada de controlar el flujo del programa, lee los datos que se han recibido en la función readFromAndroid() y en función de dichos datos, realiza una orden u otra.
  6. Funciones de movimiento: Estas funciones son las encargadas de mover el PrintBot Evolution. Estas funciones son: avanzar, retroceder, parar, izquierda, derecha, giro_180_grados, izquierdaLineas y derechaLineas. Podemos utilizar estas funciones en cualquier momento, solo tenemos que llamarlas. Por ejemplo, para utilizar la función giro_180_grados utilizamos la orden:

  7. Funciones de modos: Estas funciones se usan para que el PrintBot Evolution entre en los modos automáticos.
    1. Sigue lineas: En este modo automático se utilizan los sensores infrarrojos para detectar si el sensor está encima de una línea. En este modo se utilizan las funciones especiales de movimiento, izquierdaLineas y derechaLineas que mueven solo una rueda, en vez de las dos en direcciones contrarias, para realizar el movimiento.
    2. Esquiva obstáculos: En este modo automático se utiliza el sensor de ultrasonidos para detectar objetos y evitar chocarse contra ellos. El código de esta función es:

      Dentro de esta función, en primer lugar, encontramos las variables izq,drch y cent, que determinan la posición del mini servo que mueve el sensor de ultrasonidos. Las posiciones tienen que apuntar a la izquierda, derecha y centro respectivamente, pero puedes ajustar las posiciones a otras distintas o crear nuevas posiciones.

      Después comprobamos si hay obstáculos en la dirección a la que apunta el servo con la función buscaObstaculos(), que utilizamos para todas las posiciones pasando como dato el ángulo en el que deberá apuntar el servo. El código de la función es:

      Dentro de esta función podéis modificar la distancia máxima que utilizaremos para detectar obstáculos, es decir, cual es la distancia a partir de la cual si encontramos un objeto se considera obstáculo o no.

      Para calcular la distancia, se utilizan las funciones auxiliares Distance y TP_init que se encargan de activar el sensor Bat, enviar una señal de ultrasonidos, calcular el tiempo que tarda en leerse la señal una vez que ha rebotado y, calcular en función de dicho tiempo la distancia a la que se encuentra.

      Una vez que sabemos si tenemos o no un obstáculo delante en cada una de las tres posiciones, desplazamos el PrintBot hacia la zona que esté libre.

    3. Sigue luz: Este modo automático se utiliza para desplazar el PrintBot hacia la zona donde la intensidad de la luz sea mayor. Para ello, leemos el valor de cada uno de los pines donde están conectados los módulos LDR (del inglés, resistencia dependiente de la luz), comparamos los valores, giramos hacia el lado donde la intensidad de la luz sea mayor y movemos el PrintBot en linea recta durante 1 segundo.

Puedes ver esta entrada en ejecución en el siguiente vídeo:

Recuerda que puedes modificar cada uno de los parámetros utilizados para ajustar el funcionamiento de tu PrintBot Evolution a tu gusto. Además como ejercicio te proponemos:

  • Modifica los iconos de la aplicación de Protocoder para incluir imágenes en vez de texto en los botones.
  • Utiliza los sensores de infrarrojos para detectar precipicios. Puedes ver un ejemplo de como hacerlo aquí.
  • Puedes crear un botón para que tu PrintBot mueva la cabeza y emita un sonido.

Si quieres aprender más sobre Arduino, Protocoder y robótica, puedes seguir el Curso de programación para makers con Arduino y Protocoder