Comunicación entre procesos remotos mediante el uso de Raspberry Pi
Integrantes:
·
ESTEBAN IGNACIO MOHR FESTER
·
MATIAS ANDRES MELIVILU FREDE
Contacto:
·
esteban.mohr@sansano.usm.cl
·
matias.melivilu@sansano.usm.cl
Resumen:
El proyecto consiste en la comunicación de procesos remotos entre mini ordenadores Raspberry Pi donde una actúa como capturadora de datos de un sensor ultrasónico y mandar los datos a un servidor, otra pide los datos del servidor para graficar los datos y una tercera que pide los datos del servidor, los grafica y ademas hace funcionar un circuito de alarma en caso de que un objeto esté muy cerca del sensor.
El programa recopilador de datos del sensor y el servidor están realizados en lenguaje C, el que solo gráfica está hecho en lenguaje Java y el tercero, el que gráfica y ejecuta el circuito, está realizado en lenguaje Java con métodos nativos en C.
Introducción:
El gran crecimiento de las tecnologías IoT (“Internet of Things”), las cuales consisten en conectar diferentes dispositivos tanto domésticos como industriales a la nube, de tal manera que estos puedan comunicarse a través de ella y facilitar u optimizar ciertas tareas, han aportado de gran manera para el traspaso de información de forma remota en tiempo real.
Es por esto que el dominio en la programación de servidores que comuniquen procesos remotos toma vital importancia no solo para aplicaciones de Web, sino también para implementaciones que comuniquen sensores y actuadores en tiempo real.
Diseño de la solución:
A continuación
se presenta la arquitectura general del sistema.
La solución de este proyecto, se separa en distintas etapas, donde la primera es el programa en C llamado ultrasonico.c que se encarga de leer constantemente los valores tomados de un sensor de ultrasonido, luego de capturar un dato, ese dato es enviado a un servidor (para efectos de este proyecto es un servidor levantado en aragorn) mediante protocolo UDP. Este proceso de lectura y envío se realiza de forma constante. Este programa es ejecutado por una Raspberry Pi.
La siguiente etapa es el servidor opc.c el cual es un servidor creado en lenguaje C el cual se encarga de recepcionar los datos recibidos por protocolo UDP, para luego enviar el dato leído al cliente que lo solicite mediante protocolo TCP. Para efecto de este proyecto los clientes son las 2 Raspberry Pi que pedirán el dato al servidor para graficar y ejecutar el circuito. Este programa es ejecutado en aragorn para su funcionamiento como servidor.
La siguiente etapa del diseño es graficador.java el cual es un programa en lenguaje Java que se encarga de conectarse con el servidor opc, pedir el dato y graficarlo a tiempo real mediante el programa de Linux gnuplot. Este programa es ejecutado en una Raspberry Pi.
Como última etapa a diseñar, es el programa Lector.java, el cual se encarga de conectarse mediante protocolo TCP con el servidor opc y pedir los datos que está recibiendo este con el fin de graficarlos mediante gnuplot y además ejecutar un circuito que, según la distancia medida del sensor ultrasonido, mediante los puertos de propósito general de la Raspberry Pi, hace sonar un buzzer y ademas enciende un led de color rojo en caso de que el buzzer este sonando y si no, se enciende una luz verde.
Implementación:
Para la implementación de la
primera etapa, primero se verá la conexión que posee la Raspberry Pi con el
sensor ultrasónico:
Como se aprecia en la figura, el sensor ultrasónico consta de 4 pines, uno de alimentacion de 5V (Vcc) , un pin de tierra (GND), un pin de trigger conectado al puerto GPIO23 de la Raspberry Pi en este caso y un pin de echo conectado al puerto GPIO24 de la Raspberry Pi.
Antes de pasar a la
programación, se debe entender como funciona el
sensor ultrasónico. Este funciona con 2 pulsos, uno de trigger
y otro de echo. A continuación se muestra una figura
ilustrativa respecto:
Como se puede observar en la figura, el sensor ultrasónico funciona de la siguiente manera: Primero se dispara la señal de trigger la cual no dura más de 10 us, cuando esta se dispara, el pin de echo se levanta y la señal ultrasónica avanza en el espacio hasta que choca con un objeto y esta vuelve al sensor. Cuando la señal ultrasónica llega de vuelta al sensor, este coloca el pin de echo en bajo y mide el tiempo que tardó la onda ultrasónica en ir y volver para así poder calcular la distancia de un objeto.
Una vez comprendido esto, se puede pasar a la codificación del programa ultrasonico.c, el cual en primer lugar necesita la librería de wiringPi la cual se encarga de mapear los puertos GPIO de la Raspberry Pi en lenguaje C (contar con esta librería es crítico). Ya con la librería adquirida en la Raspberry Pi, en el programa en C se crea el socket UDP por el cual se mandará el dato de distancia en centímetros capturado por el sensor hacia el servidor opc. Luego se crean 2 funciones las cuales son getSonar() la cual se encarga de obtener la medición hecha por el sensor ultrasónico en centímetros y pulseIn() que lee más tiempo del pin echo. Luego en un ciclo while infinito (while(1)) se realiza la medición y una vez obtenida ésta, es mandada por el socket UDP al servidor opc.
Para la implementación del servidor opc se generan 2 hebras. La primera se encarga de atender a la conexión UDP, o sea, se encarga de recibir los datos que se encuentra midiendo el sensor de ultrasonido, y la otra hebra se encarga de atender a los clientes TCP que deseen acceder a los datos. Cada vez que la conexión TCP recibe un caracter ‘n’ este manda el dato actual que esté almacenado en el servidor al cliente solicitante.
Para la implementación del programa graficador.java, primero se establece conexión habilitando el socket TCP para realizar la conexión con el servidor. Luego, se manda el carácter ‘n’ de forma periódica para recibir los datos de medición, para luego que el programa mute usando a una instancia de gnuplot, e ir pasandole mediante pipa los datos a gnuplot para que este vaya graficando los datos y los mantenga en el gráfico, obteniendo un gráfico de tiempo real.
Para la última etapa, primero se
debe considerar que como está raspberry usará puertos
GPIO, debe tener la librería wiringPi anteriormente
mencionada. Antes de hablar de código, se presentará el circuito usado para la
alarma compuesta por un buzzer y 2 leds:
Para el funcionamiento del buzzer, se considera un modelo con transistor PNP (considerar esto ya que si se usa un NPN la configuración cambia), el cual funciona con lógica negativa, lo que quiere decir que, cuando el puerto GPIO está bajo, el buzzer suena El puerto GPIO conectado al buzzer es el puerto GPIO17 de la Raspberry Pi.
Para el caso de los leds, se opta por una configuración de lógica positiva, lo que quiere decir que si el puerto GPIO está en alto, el led está encendido.Para el led rojo, se usa el puerto GPIO20 y para el led verde se usa el puerto GPIO21 de la Raspberry Pi.
El programa Lector.java funciona con 2 hilos de ejecución, el hilo principal de ejecución, que recibe los parámetros de la consola, configura el socket para la comunicación remota y crea un proceso hijo el cual ejecuta GNUPlot. Este proceso, se comunica con su proceso padre a través de una pipa, la cual entrega los textos de los comandos a ejecutar.
El hilo secundario de ejecución llamado “Beep Thread” se encarga de hacer sonar el buzzer vibrador en los momentos que corresponde. Ya que los puertos de uso general (GPIO) de la Raspberry es programada en C, se crea una librería de métodos nativos llamada BeepLib.c, lacual es usada para importar al código de Java, los métodos beepSetup() que está encargado de configurar los puertos de entrada y salida y beepHandle(lastValue), encargado de hacer sonar el buzzer y cambiar el encendido de las led, si es que el último valor medido es menor al umbral designado.
Pruebas y Resultados:
Para la primera prueba, se
ejecuta medicion.c con la configuración planteada
anteriormente y se muestran por consola los valores obtenidos por el sensor
obteniendo el siguiente resultado:
En esta captura se aprecia como el sensor mide la distancia en centímetros.
Como segunda prueba es al mandar
los datos a aragorn, este imprime los valores
enviados obteniendo la siguiente respuesta:
Como se puede observar, los datos llegan de manera correcta al servidor levantado en aragorn.
Ahora en una de las Raspberry Pi
se procede a ejecutar graficador.java obteniendo el siguiente resultado:
Como se aprecia en la imagen, se puede observar los cambios realizados al momento de acercar un objeto al sensor.
Como prueba final se procede a ejecurar Lector.java en la tercera Raspberry Pi conectado
al circuito de alarma ya descrito anteriormente, donde se puede observar su
funcionamiento en las siguientes figuras:
Como se aprecia en las figuras anteriores cuando un objeto está cerca del sensor, este enciende una luz roja, y en ese momento suena el buzzer, cuando un objeto no está cerca del sensor, no suena el buzzer y se mantiene encendido un led verde para indicar que no hay objetos cercanos.
Por ende, las pruebas resultaron en éxito con el propósito planteado.
Conclusiones y trabajo futuro:
La implementación y pruebas dan a cuentas de que el proyecto cumplió con sus objetivos de manera exitosa. Esta sirve como proyecto base o plantilla para otras aplicaciones más grandes y/o sofisticadas, por ejemplo, el sensor puede ser cambiado por una aplicación móvil, el cual active el o los actuadores a utilizar (que pueden ser de muchos tipos). Para el servidor es posible ampliar su funcionalidad utilizando otros servicios de nube que existen, por ejemplo, la utilización de la nube de amazon web services (AWS) en conjunto con el sistema operativo en tiempo real de amazon (RTOS).
Concepto utilizados:
·
Creación de procesos y su mutación usando exec.
·
Programación multi hebras en Java y C
·
Invocación de métodos nativos en C desde Java
·
Comunicación de procesos vía TCP y UDP
Referencias:
·
Contenidos del curso Programación de Sistemas del profesor
Agustín Gonzalez
Enlace a código fuente: