Universitat Oberta de Catalunya

MyRobot . Diseñando un robot con Arduino.

Asignatura: Diseño de interacción

Titulación: Grado Multimedia

Nombre del estudiante: Pedro Puertas Estivill

Profesor: Santiago Vilanova Angeles

Introducción

La asignatura de Diseño de interacción nos adentra en el apasionante mundo de la electrónica y en cómo crear interfaces multimedia con ella. 

Arduino es sin duda una revolución para el mundo multimedia, ya que permite crear sin excesivas complicaciones pequeños dispositivos creativos que permiten traspasar la creatividad de un monitor a sistemas complejos de luces y motores. Además, permite interactuar de varias formas con el usuario mediante sensores que son fácilmente conectables con el microcontrolador. 

En este artículo vamos a hablar de la creación de un pequeño robot que es capaz de desplazarse en todas las direcciones, girar sobre sí mismo, mover la cabeza y emitir sonidos o música. Todo ello controlado desde una aplicación móvil o desde una página web.

Acabado final del robot  construido con un Arduino Uno y gestionable a través de una aplicación Android.

Etapas y retos

La creación del robot ha pasado varias etapas, de diseño conceptual, creación de un esqueleto funcional, desarrollo de los programas y ensamblado final.

Diseño conceptual

La primera etapa fue la de definir qué funcionalidades debía tener el robot. Una parte de ellas estaba influenciada por los requisitos mínimos de la propia práctica de la asignatura, en la cual se define que deben utilizarse un mínimo de dos técnicas de interacción que no pueden ser teclado y ratón. Además, es recomendable establecer algún tipo de comunicación con el exterior, y se recomienda el uso de Processing.

En mi caso, me decidí por la creación de un robot que llevaba tiempo pensando hacer pero nunca encontraba el momento. Así que fue mi excusa perfecta para desempolvar material viejo que había ido acumulando, como ruedas de coches teledirigidos, cables, etc. El primer reto fue definir la forma que tendría el robot y los materiales necesarios. En este caso, el cuerpo del robot está formado por una antigua bobina de CD y la cabeza es un bol de plástico de un diámetro similar al de la bobina.

Elección de los materiales que darán forma al robot.
Ensamblaje de dos motores servo de rotación continua.

Para mover el robot se han utilizado dos servomotores de rotación continua. Este tipo de servomotores tiene una modificación que les permite girar 360 grados; no se controla el ángulo, sino la dirección de giro y la velocidad, lo que permite tener un control muy exacto del movimiento que se realizará. En cambio, para la cabeza del robot se ha utilizado un servo de 180 grados, que permite indicar el ángulo en el que se desplazará el eje del motor.

Ensamblaje de la placa controladora Arduino UNO.

Una vez ensamblada la parte motora, se ha desarrollado toda la programación de control de motores. La única particularidad destacable al respecto es que, al estar los motores enfrentados, es necesario hacerlos girar inversamente; es decir, si queremos que el robot se desplace hacia delante, un motor debe girar en el sentido de las agujas del reloj y el otro justo al contrario, de forma que al posicionarse en el suelo se desplazarán en la misma dirección.

Para utilizar un servo, es necesario importar la librería servo.h y asociar un pin de control a cada servo. Veamos un ejemplo de código:

#include <Servo.h>
Servo motorE;  // crea el objecto motor izquierda
Servo motorD;  // crea el objecto motor derecha
Servo motorCAP;
// Definimos los diferentes pins conectados a cada motor
#define pinMotorE   8
#define pinMotorD   10
#define pinMotorCAP 11

// Rutina principal, inicia el sistema
void setup() {
  motorE.attach(pinMotorE); // Asociamos los pins de los motores
  a la libreria
  motorD.attach(pinMotorD);
}

void loop() {
  motorE.write(180); // Máxima potencia en cada motor pero
  sentido contrario
  motorD.write(0);
  delay(2000);
  motorE.write(0);        
  motorD.write(180);
  delay(2000);
}

Conexionado

Las conexiones entre los motores y las dos placas controladoras se han realizado con una placa de prototipo soldando diversos pines para adaptarlos a los pines hembras que suministra la placa Arduino UNO, de este modo, el acabado y el conexionado se realizan de una forma muy limpia y se evitan falsas conexiones de las placas protoboard, que son muy funcionales para realizar pruebas pero no están indicadas para un proyecto con acabado final, principalmente porque, con el movimiento del robot, fácilmente podrían producirse falsos contactos y que dejara de funcionar.

Para que las conexiones sean sólidas, es necesario utilizar el soldador para unir todos los pines, también es importante intentar utilizar colores descriptivos de cada conexión; por ejemplo, se ha utilizado el rojo para la alimentación, el negro para la masa y el amarillo para las conexiones de datos.

En la placa de conexiones, se han habilitado varios conectores del tipo pin para conectar los tres motores, de forma que sea fácil desensamblarlo en el caso de que haya que sustituir alguno de los motores. De esta placa también sale un cable de conexiones para conectar la placa de comunicaciones con la de Arduino, que une los pines RX, TX y masa de ambas placas.

Placa de prototipo.

Módulo de comunicaciones

Una vez testado el correcto comportamiento de la parte motriz, se desarrolló una de las partes más importantes: la comunicación del robot con el exterior. Arduino tiene varias formas de comunicarse con el exterior, tanto de forma cableada como de forma inalámbrica, pero sin duda una de las más potentes es la de poder incorporar conexiones wifi al sistema, de forma que se pueda comunicar con cualquier aparato que disponga de esta tecnología, como es el caso de móviles, ordenadores y tabletas.

Para poder conectar Arduino con la tecnología WIFI, existe un pequeño microcontrolador de la empresa Espressif, el ESP8266 (link https://programarfacil.com/podcast/esp8266-wifi-coste-arduino/). Existen diferentes variantes de este módulo, unas permiten conectarlo al Arduino y a través de comando AT gestionar la comunicación. Otras versiones permiten desarrollar un programa interno desde el propio IDE de Arduino, lo que permite aplicar toda la lógica de las comunicaciones en el propio chip y descargar de esta tarea a Arduino.

Ha sido esta la solución adoptada con una placa Lolin ESP12 (link https://www.infootec.net/nodemcu-esp12/). Esta placa permite la programación a través de un puerto USB. Para comunicarse con el Arduino se utilizará el puerto serie de forma que todos los comandos que se reciban a través del wifi se comunicarán a Arduino a través del puerto serie.

Placa de desarrollo Lolin ESP12.

Para poder ser operativo y funcional en cualquier red, era necesario que no hubiera variables fijas en el código, es decir que el nombre de la red WIFI, contraseña, etc. no podía estar como una constante en el código porque en ese caso el robot sólo se podría usar en una única ubicación. Para ello es necesario poder acceder al robot, configurarlo indicándole a que red wifi se debe conectar, de ese modo podrá ser manejado desde varios móviles, página web, etc. Para conseguir esta funcionalidad se usa inicialmente el modo AP, en el cual el módulo ESP8266 crea una red wifi propia, que en este caso he llamado MyRobot, una vez conectado a esa red wifi, se puede enviar una configuración del nombre del wifi, contraseña e IP, una vez recibida, el módulo se intenta conectar y si lo consigue almacena la configuración en la eeprom y se reinicia. Al reiniciarse, lee la configuración de la eeprom y se conecta a la red wifi. A partir de ese momento ya es posible enviarle comandos. 

El protocolo utilizado para enviar comando desde el móvil o una web incluye un encabezado formado por el carácter @ y un final de paquete formado por el carácter $, por ejemplo el comando @SOUND$ solicita al robot que toque la marcha imperial.

Desarrollo de la aplicación

La aplicación se ha realizado con dos variantes, una en Android y otra en versión WEB. En la asignatura no se incluye la programación en Android, pero en este caso no es una aplicación muy complicada, ya que se basa en la detección de las pulsaciones recibidas en unos botones. El entorno de trabajo utilizado ha sido Android Studio, el cual facilita las tareas del desarrollo y la creación visual de las pantallas.

Entorno de desarrollo integrado para crear la aplicación.

La parte más destacable por comentar en el artículo es la del reconocimiento de voz, que utiliza el motor interno de Android para convertir la voz en ordenes que serán enviadas al robot a través de la red WIFI.

Para poder reconocer voz, se debe utilizar el componente SpeechRecognizer (https://developer.android.com/reference/android/speech/SpeechRecognizer), el componente necesita además que la clase implemente un gestor de los eventos de reconocimiento (RecognitionListener).


public class MainActivity extends Activity implements
RecognitionListener, View.OnTouchListener, Callback {

La inicialización del componente se realiza con las siguientes instrucciones, indicando que el “listener” es la propia clase (this).

// Iniciar el reconeixement de veu
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(this);
mSpeechRecognizerIntent = new Intent(RecognizerIntent.
ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.
EXTRA_LANGUAGE_MODEL, RecognizerIntent.
LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.
EXTRA_CALLING_PACKAGE, this.getPackageName());

El RecognitionListener obliga a implementar diversos métodos que serán llamados cada vez que se produzca un evento relacionado con la voz. El más relevante no obstante es el que el gestor llama cuando ya ha obtenido resultados.

Los resultados obtenidos se pueden analizar en una lista de Strings, que podemos compararla con las ordenes que tenemos previstas. Por ejemplo para que el robot gire a la derecha, se han previsto dos variantes de la orden, “girar derecha” y “derecha” por lo que se deben comparar con ambos valores para emitir la orden hacia el robot, esto se realiza como se puede apreciar en el código con la función contains.


if (matches.contains("girar derecha") || matches.contains("derecha")) {
        Communicator.sendToRobot("@DRETA$", this);
        return;
}

En este caso, si las palabras reconocidas coinciden con girar derecha o derecha, se envía la orden @DRETA$ al robot.

La clase Communicator encapsula todas las comunicaciones a realizar con el robot, es una clase sencilla que abre un socket en el puerto 80 y envía las cadenas de texto indicadas por el programa.

/**
 * Función que analiza los resultados y controla el robot con la voz, en este 
punto se podría trabajar toda la
 * lógica para hacer el robot más inteligente, de hecho lo que se hace es dar 
la "inteligencia" desde el teléfono
 *
 * @param results
 */
public void onResults(Bundle results) {
   ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.
RESULTS_RECOGNITION);

    if (matches == null) return;

    if (matches.contains("como te llamas")) {
        Communicator.sendToRobot("@SAY Mi nombre es MyRobot $", this);
        return;
    }
    if (matches.contains("hola")) {
        Communicator.sendToRobot("@SAY Hola $", this);
        return;
    }
    if (matches.contains("girar derecha") || matches.contains("derecha")) {
        Communicator.sendToRobot("@DRETA$", this);
        return;
    }
    if (matches.contains("girar izquierda") || matches.contains("izquierda")) {
        Communicator.sendToRobot("@ESQUERRA$", this);
        return;
    }
    if (matches.contains("avanzar") ||  matches.contains("avanza") || 
        matches.contains("arranca")) {
        Communicator.sendToRobot("@ARRANCA$", this);
        return;
    }
    if (matches.contains("retroceder") || matches.contains("retrocede") || 
        matches.contains("atras")) {
        Communicator.sendToRobot("@ENRERE$", this);
        return;
    }
    if (matches.contains("parar") || matches.contains("para")) {
        Communicator.sendToRobot("@PARA$", this);
        return;
    }
    if (matches.contains("di no")) {
        Communicator.sendToRobot("@NO_NO$", this);
        return;
    }
    if (matches.contains("sonido") || matches.contains("musica")) {
        Communicator.sendToRobot("@SOUND$", this);
        return;
    }
    if (matches.contains("guapa") || matches.contains("guapo") 
|| matches.contains("silba")  ) {
        Communicator.sendToRobot("@SILBA$", this);
        return;
    }
    if (matches.contains("vuelta") || matches.contains("vuelta derecha")) {
        Communicator.sendToRobot("@VOLTA_D$", this);
        return;
    }
    if (matches.contains("vuelta izquierda")) {
        Communicator.sendToRobot("@VOLTA_E$", this);
        return;
    }
 }

Ensamblado final

Con todo desarrollado y funcionando, la fase final es encajar las diferentes piezas, alimentación, etc. Y realizar una prueba real antes de dar el acabado de pintura.

Fase del ensamblaje final.

Una vez comprobada la completa funcionalidad del prototipo, se ha pintado y decorado para darle un aspecto amigable. Se ha pintado con un espray de color plata, para ello se han vuelto a desensamblar todas las partes, se han cubierto las zonas sensibles con cinta para pintar y se han dado tres manos de pintura, se ha dejado un tiempo de secado entre la primera y la segunda capa de tres horas, y con la capa final de ocho horas.

Fase de pintado y decoración del robot.

En estos vídeos se puede ver funcionando el robot en la fase de pruebas y en la entrega final.

Conclusiones

Esta asignatura es realmente interesante, creo que para disfrutarla es recomendable disponer de suficiente tiempo para investigar los muchos apartados que se plantean en ella. Es una asignatura exigente si se quiere obtener una calificación alta, ya que los consultores valoran mucho el acabado final y la originalidad de los diferentes proyectos. Lo cual requiere un esfuerzo adicional a lo indicado en los enunciados, pero el esfuerzo nos permitirá profundizar mejor en todos los conceptos aprendidos. Particularmente, me he quedado con ganas de implementar la parte de la asignatura de visión artificial, una parte muy interesante y que plantea proyectos fascinantes, quizás algún día MyRobot deje de ser ciego para ver el mundo a través de sus ojos de porespán.

Enlaces relacionados:

Documentación:


Cita recomendada: PUERTAS ESTIVILL, Pedro. MyRobot. Diseñando un robot con Arduino. Mosaic [en línea], junio 2019, no. 172. ISSN: 1696-3296. DOI: https://doi.org/10.7238/m.n172.1936.

Acerca del autor

Analista y autodidacta trabaja como jefe de proyectos informáticos en el departamento de I+D de una importante empresa de logística y transporte. Experto en programación en C++ , JAVA, tecnologías web y bases de datos. Actualmente cursa el grado Multimedia en la UOC con el que está explotando su faceta más creativa.

Un comentario

Deja un comentario

Deja un comentario