Introducción
En este artículo vamos a ver una solución descargable que consiste en una cinta transportadora hecha en Unity, cuyo funcionamiento es controlado utilizando una placa Arduino.
Archivos para descargar
En el siguiente paquete encontrarás dos carpetas, una con los archivos de Unity y otra con los archivos de Arduino.
Dentro de la carpeta Unity encontrarás una compilación para probar la simulación y también un paquete de Unity que puedes importar en tu proyecto y acceder a los assets de esta simulación.
Grabar programa en Arduino
En las descargas encontrarás una carpeta llamada «Arduino», que contiene el programa que se encarga de leer las entradas digitales, formar una palabra y enviarla por el puerto serial.
El programa es bastante simple por lo que funcionará en cualquier placa Arduino que puedas conseguir, en mi caso usé un Arduino Mega.
En el siguiente video se puede ver cómo grabar el programa en la placa Arduino, necesitarás el software de Arduino.
Circuito para las entradas digitales
El programa de Arduino que viene en la descarga utiliza los pines 2 y 3 para las entradas digitales. El pin 2 controla el estado de la máquina alimentadora y el pin 3 controla el estado de la cinta transportadora.
Hay muchas formas de conectar señales a la entrada digital del Arduino, voy a mostrar dos alternativas utilizando switches.
ADVERTENCIA
ASEGURARSE DE CONECTAR BIEN LOS ELEMENTOS AL ARDUINO, UN CORTOCIRCUITO PUEDE DESTRUIR LA PLACA.
ES NECESARIO CONOCER LA DISTRIBUCIÓN DE PATAS DE CADA CONTACTO EN PARTICULAR, MEJOR SI SE DISPONE DE UN TESTER PARA MEDIR CONTINUIDAD.
Alternativa 1: Switch de dos posiciones
En mi caso usé switches de dos posiciones para las entradas digitales, en estos switches el terminal del medio hace contacto con un extremo o el otro dependiendo de la posición en la que esté el switch. Por lo tanto, en los extremos conectamos las señales de voltaje alto y bajo (en mi caso 5 Volts y 0 Volts respectivamente). El terminal del medio del switch se conecta a la entrada digital del Arduino.
Reitero la advertencia, el switch que usé es como el que se observa en la figura 1 y en este caso en particular se conecta de esa forma.
Alternativa 2: Interruptor con resistencia pull-up
Tal vez sólo dispones de un switch interruptor, es decir un contacto que se cierra o se abre. En las entradas digitales del Arduino debe haber constantemente señales de voltaje alto o bajo, no debemos dejar entradas digitales sin conectar a nada (conexión al aire como le decimos acá) ya que esto conducirá a comportamientos impredecibles.
Para esto hay que implementar un pequeño circuito con resistencia pull-up, como el que se observa en la figura 2.
En este caso usamos una resistencia conectada al terminal GND del Arduino y el otro extremo conectado por un lado a la entrada digital y por otro al switch interruptor, el otro extremo del switch lo conectamos a la señal de voltaje alto (5 Volt por ejemplo).
El circuito de la figura 2 funciona de la siguiente manera: cuando el interruptor está abierto no hay circulación de corriente a través de la resistencia, por lo tanto los 0 Volts se trasladan a la entrada digital y el Arduino lee un nivel bajo. Cuando accionamos el switch la corriente circulará por la resistencia y en la entrada del Arduino habrá una señal de nivel alto.
Comprobar que el programa Arduino está funcionando
El programa de Arduino se encarga de leer el estado de las entradas digitales, crear una palabra binaria que representa esos estados y enviarla por puerto serie.
Si abrimos el monitor Serie, desde la pestaña Tools, deberíamos ver los estados de las entradas digitales mensajes. Como se observa en el siguiente video.
Probar la simulación
Una vez que hemos grabado el programa en la placa Arduino, podemos ejecutar la compilación que viene en la descarga.
Al entrar en la simulación, en la esquina superior izquierda hay un botón para conectar Unity con la placa Arduino.
En esta parte pueden surgir problemas con la conexión, probablemente corrija esto en otra versión de la solución. Para asegurarse de que la conexión funcione, la placa Arduino debe estar conectada antes de abrir la compilación y el proceso de conexión puede tardar varios segundos en concretarse. Si luego de 30 segundos la placa no se ha conectado, verificar el paso anterior y volver a abrir la simulación e intentar de nuevo.
Video 3: Prueba de la cinta transportadora en Unity controlada por Arduino.
Importar paquete y corregir error API Compatibility Level
Para acceder a los archivos fuente de la simulación está el paquete de Unity, lo puedes importar como se ve en el siguiente video.
Video 4: Importar paquete y corregir error de API Compatibility Level.
Al importar el paquete nos aparecerán errores ya que algunos Scripts no pueden acceder al paquete con las clases que permiten acceder al puerto serie.
Para solucionarlo seguimos los pasos que se ven en el video 4. Vamos a la pestaña Edit > Project Settings > Player > Other Settings y en el campo «API Compatibility Level» seteamos «.NET 4.x».
Funcionamiento de la cinta transportadora en Unity controlada por Arduino
Dentro del paquete está la escena que se ve en la simulación, podemos acceder a ella y ver sus elementos, en la figura 3 podemos ver la jerarquía de la escena.
En la jerarquía tenemos tres máquinas, «Toori Machine» es la máquina que se encarga de colocar objetos sobre la cinta transportadora. «GDT Conveyor Belt» es la cinta transportadora y «Box» es la caja donde caen los objetos y son destruidos.
Cinta transportadora
La cinta transportadora es un modelo 3D con una estructura y una banda.
Para lograr la animación del funcionamiento lo que se hace es agregar offset al mapa UV de la textura. En este caso como la textura se encuentra distribuida verticalmente agregamos offset a la componente Y del mapa UV. Cuando el mapa UV tiene un offset de 1 en la componente Y la textura vuelve al estado inicial.
Entonces para lograr el efecto de que la cinta transportadora avanza o retrocede incrementamos gradualmente el offset del mapa UV en alguna de las componentes.
Para lograr que la cinta transporte objetos, se tiene un box Collider en modo Trigger que detecta cuándo un objeto está sobre la cinta, estos objetos deben tener asignada una componente RigidBody.
Entonces en el Script de la cinta transportadora se define la función OnTriggerStay que se llamará cuando un objeto esté sobre la cinta transportadora. Esta función se encargará de mover el objeto, para sincronizar el movimiento de la cinta con el movimiento del objeto hay un parámetro en el inspector llamado «SyncUVMovementFactor», por defecto está seteado en 2, como se observa en la figura 2.
La cinta transportadora tiene una función pública que permite activarla o desactivarla y que puede ser llamada desde cualquier otro Script. Ejecutamos esta función con la información que leemos de la placa Arduino, es decir se activará o desactivará de acuerdo al estado de la entrada digital 3 de la placa.
Máquina alimentadora
Para que la simulación sea un poco más completa se incluye una máquina que coloca objetos sobre la cinta transportadora. Esta máquina se controla con el Script «FeedingMachine» y también tiene un método público que permite encenderla o apagarla. Esta máquina se controlará con la entrada digital 2 del Arduino.
En el inspector podemos colocar el prefab de los objetos que debe colocar sobre la cinta transportadora y podemos cambiar los tiempos entre un objeto y otro.
Comunicación entre Arduino y Unity
Esta parte se resuelve utilizando una versión modificada de la solución WRMHL compartida por el equipo RELATIVTY. Te animo a visitar los links para ver la solución original y los proyectos.
Para poder comunicar Unity con Arduino se debe tener un GameObject en la jerarquía con el Script «wrmhlRead» asignado.
He agregado un entero llamado «arduinoMessageLength» en el inspector, que indica la longitud de la palabra binaria que se envía desde el Arduino. Esto se utiliza para sincronizar correctamente Unity con Arduino en caso de existir más dispositivos utilizando el puerto serie.
En nuestro caso, como desde el Arduino enviamos una palabra de dos dígitos, en ese campo se debe poner dos. En caso de agregar más dígitos a la palabra, se debe modificar apropiadamente este campo.
La lectura del mensaje del Arduino se hace en el método «ReadMessageAndAction()». Aquí adentro podemos realizar la acción que queramos en Unity. En nuestro caso ejecutamos los métodos públicos de los Scripts ConveyorBelt y FeedingMachine, para activar o desactivar las máquinas de acuerdo a la orden del Arduino.
Conclusión
Hemos visto cómo funciona la solución de la cinta transportadora en Unity controlada por Arduino.
Con los archivos provistos se puede crear una nueva simulación de acuerdo a las necesidades de cada uno.