domingo, 10 de abril de 2016

Streaming de datos por TCP en Raspberry Pi + LabVIEW

 Si se desea hacer un streaming de datos desde un sistema de instrumentación remota como una estación meteorológica, sismológica o un telescopio robótico, puede resultar muy útil y económico tener un servidor TCP en un Raspberry Pi y visualizar los datos en tiempo real con LabVIEW desde cualquier lugar. Esto puede hacerse muy fácilmente utilizando el modulo socket para Python.

Un socket es una abstracción de programación para la representación de conexiones y permiten realizar una comunicación bidireccional. En Python se crea de la siguiente manera:

import socket
s = socket.socket()    #Instaciamiento para el objeto 's'
host = ''                      #Host local por defecto
port = 8006                #Puerto
s.bind((host,port))     #Asignación de dirección y puerto a la instancia
s.listen(5)                  #Número máximo de conexiones entrantes 

Para este ejemplo simularemos 2 señales que usaremos para enviar por TCP. En una aplicación real estas señales serían adquiridas mediate ADC's u otros dispositivos conectados a los pines GPIO de la tarjeta:

t = np.linspace(0,2*np.pi,100)
y0 = np.float16(np.sin(t))
y1 = np.float16(0.5*np.sin(t)*np.sin(2*t))

Se puede observar que estoy usando la función float16() para reducir la precisión de los datos para ahorrarle un poco de trabajo al cliente en LabVIEW pero pueden omitirla si requieren más dígitos significativos. Ahora, para parte principal del programa tenemos:

print u"Esperando conexión"
s, addr = s.accept()
print u"Conexión desde: ", str(addr)
i = 0
try:
 while True:
     s.send('CH0'+str(y0[i])+'\n')
     s.send('CH1'+str(y1[i])+'\n')
     i += 1
     if i>=99:
         i = 0
     time.sleep(0.01)
except KeyboardInterrupt:
s.close()

 Observen que en el argumento del método send() estoy concatenando las etiquetas de 'CH0' y 'CH1' para poder separar las señales después con LabVIEW. (recuerden que '\n' es una secuencia de escape que indica nueva linea).

El diagrama a bloques del cliente para LabVIEW es bastante sencillo:
(Click para agrandar)
En el bloque TCP Open Conection colocamos la dirección IP* de la Raspberry y el puerto que establecimos para el socket en el programa de Python. Después de hacer la lectura utilizamos los bloques Match Patern para identificar las etiquetas de los canales y separar sus valores. Finalemnte se convierten las cadenas aisladas a numeros de tipo double para enviarlos al graficador. El sistema funcionando se ve así:


*Aquí estoy usando una ip local. En la práctica se requerirá utilizar una IP pública. Hay varias formas de hacerlo: #1, #2 , #3

Referencias:
Python Advanced Tutorial 6, DrapsTV
Raspberry Pi + Arduino + LabVIEW, Alfredo Cruz

No hay comentarios: