Sunteți pe pagina 1din 10

Software de adquisicin de datos para el dispositivo USB4000

Comunicacin a travs del puerto USB del dispositivo USB4000

Nombre y apellidos: Nria Pujol Vilanova Categora en el concurso: Sistemas Universidad: EPSC (UPC) Titulacin: Ing. Telecomunicaciones (2 Ciclo)

1 INTRODUCCIN
El siguiente documento describe, a modo de resumen, las principales funcionalidades del software desarrollado en una de las primeras fases del proyecto: TestingUSB4000.py. Este sencillo software pretende testear la comunicacin USB entre el dispositivo USB4000 y un PC (sustituido en fases posteriores por un dispositivo tipo PDA) y comprobar la correccin de los datos obtenidos: sigan las especificaciones del datasheet y tengan coherencia con la configuracin realizada.

2 ESTRUCTURA Y FUNCIONALIDADES DEL CDIGO


La prueba de comunicacin con el dispositivo USB4000 consiste en un sencillo software, al que dado un determinado tiempo de integracin introducido por teclado, muestra por pantalla los datos obtenidos y algunos parmetros de comprobacin. El cdigo sigue la siguiente estructura secuencial:

Comprobacin de disponibilidad del dispositivo USB4000 a travs de su identificador idVendor. El dispositivo suele estar disponible cuando se encuentra conectado en el puerto USB, si an as aparecen problemas puede ser debido a la mala o no instalacin de la librera pyUSB de Python o que el identificador idVendor buscado no sea el del dispositivo conectado. Aparicin por pantalla de los valores del vector de configuracin del dispositivo USB4000, dnde podemos comprobar el valor actual del tiempo de integracin. Peticin por pantalla del nuevo tiempo de integracin que deber ser introducido por el usuario a travs del teclado. En la pantalla aparece: Type integration time(from 10 to 65.000.000us): Validacin del valor del tiempo de integracin introducido segn el rango especificado por el fabricante. Si el valor introducido se encuentra fuera del rango vlido, la ejecucin del programa es interrumpida y se aparece por pantalla el mensaje: Non valid Integration Time value. Si el valor introducido cumple la condicin anterior (dentro del rango) se procede a modificar su formato para adaptarlo al especificado por datasheet del dispositivo y poder ser enviado a travs de la puerto USB. A travs del puerto USB, igual que en el caso de el puerto serie, slo podemos transmitir/recibir datos en formato char o string. Aparicin por pantalla de los valores del vector de configuracin del dispositivo USB4000 por segunda vez. Nos permite comprobar si el valor del tiempo de integracin ha sido modificado correctamente. Peticin de adquisicin de datos espectromtricos al dispositivo USB4000 por parte del PC. Lectura de los datos obtenidos. Se obtiene una sola lectura de 7680 bytes que equivalen a 3840 valores (puntos de una grfica). Cambio de formato de los datos obtenidos para poder ser representados (el dispositivo da el valor de cada pxel separado en 2 bytes). Representacin grfica de los datos obtenidos.

A partir de los resultados grficos obtenidos en diferentes pruebas podemos validar los datos adquiridos. La signatura espectral (grfico obtenido) debe tener la forma conocida de un fluorescente (luz de laboratorio) y la amplitud de la misma debe variar proporcionalmente con el valor del tiempo de integracin. En el prximo apartado se explican las principales funcionalidades del cdigo descrito anteriormente.

3 PRINCIPALES FUNCIONALIDADES
A continuacin se explican las funcionalidades ms importantes del cdigo desarrollado, haciendo muchas veces referencia al datasheet del dispositivo y al uso de algunas libreras Python utilizadas. No ser tanto una explicacin detallada de las lneas de cdigo sino una gua para comprender y replicar algunas de las funciones llevadas a cabo.

3.1 BSQUEDA DEL DISPOSITIVO USB Y ESTABLECIMIENTO DE LA CONEXIN


El lenguaje Python dispone del mdulo pyUSB, especfico para la comunicacin USB entre dispositivos, el cul utilizaremos en el establecimiento de la conexin y en todas las funciones relacionadas con este tipo de comunicacin. Cualquier dispositivo USB dispone de un gran nmero de atributos relacionados con su descripcin, configuracin, comunicacin, etc. Dentro de los denominados descriptivos encontramos el atributo idVendor (identificador nico de fabricante), que en nuestro caso utilizaremos para identificar el dispositivo USB4000 conectado al PC y abrir la comunicacin con l. El idVendor en los dispositivos USB4000 contiene el valor hexadecimal 0x2457, tal y cmo indica su datasheet. Como curiosidad, comentar que a travs del comando lsusb -v de Linux obtenemos el listado de todos los atributos de los dispositivos USB conectado en nuestro PC, as cmo de los de los puertos USB disponibles. Para acceder a un determinado dispositivo conectado en cualquiera de los puertos USB de un PC y establecer la conexin debemos tener en cuenta la estructura de las clases y funciones definidas segn el mdulo pyUSB, representada en el siguiente esquema:

Para poder establecer la conexin con el dispositivo USB4000 deberemos recorrer todos los objetos de tipo Device de los diferentes objectos de tipo Bus en busca de un dispositivo cuyo idVendor coincida con el buscado. Una vez encontrado el dispositivo y aplicado su propia funcin open() obtenemos un objeto de tipo DeviceHandle, la nica clase de objetos que disponen realmente de los mtodos de lectura/escritura sobre la comunicacin USB. Con la llamada de la funcin open() y la asignacin del objeto tipo DeviceHandle a una variable podemos dar por establecida la conexin.

A continuacin mostramos las lneas de cdigo Python dedicadas a este fin. import usb buses = usb.busses() for bus in buses : for device in bus.devices : if device.idVendor == 0x2457: print "USB400 Found" dev=device else: print "Another type of device found" handle= dev.open() Referente al cdigo anterior, si durante su ejecucin se dispone de ms de un dispositivo USB conectado al ordenador (un penDrive, por ejemplo) aparecern los dos mensajes: USB4000 Found refirindose al dispositivo USB4000 y Another type of device found en referencia al otro dispositivo, cuyo idVendor no coincide con el buscado. Si se ha encontrado el dispositivo obtendremos una variable handle (HandleDevice Object), asociada a una comunicacin abierta con un dispositivo USB a travs de la cual podremos escribir y leer datos del dispositivo usando los mtodos de la librera pyUSB.

3.2 MTODOS DE LECTURA Y ESCRITURA


Para poder hacer las lecturas y escrituras que nos permite el dispositivo (escribir el tiempo de integracin, leer la configuracin del dispositivo, leer datos espectromtricos, cambiar datos de configuracin, etc.) es preciso utilizar los mtodos bulkRead y bulkWrite de las clase DeviceHandle y seguir los parmetros de configuracin marcados por el fabricante. Para realizar cualquiera de las acciones permitidas sobre el dispositivo, en primer lugar debemos enviar el comando correspondiente a la accin a realizar (en el datasheet del dispositivo aparecen todos los comandos en la tabla USB Command Summary) y por lo tanto, el primer paso de cualquier accin ser escribir este comando en el dispositivo siguiendo el siguiente formato: o=handle.bulkWrite(0x01, comando) El mtodo bulkWrite requiere dos parmetros de entrada. El primer parmetro es la direccin del endpoint a utilizar al escribir comandos (0x01 en este caso) y el parmetro comando corresponde al cdigo hexadecimal de la accin a realizar una vez pasada a formato char. Por ejemplo, en el caso de querer cambiar el tiempo de integracin consultaramos la tabla USB Command summary del datasheet y obtendramos que el comando para set integration time corresponde al command byte value 0x02. ste valor, tal y cmo ya hemos comentado, se debe pasar a formato char antes de ser utilizado por el mtodo bulkWrite, lo que en el lenguaje Python se traduce como comando=chr(0x02). Anlogamente, para leer cualquier informacin se debe utilizar el mtodo bulkRead, sucediendo a la llamada del mtodo bulkWrite con el comando de alguna accin de lectura (0x09 para el caso de lectura espectral, por ejemplo). La llamada al mtodo bulkRead, muy similar a la del mtodo bulkWrite, sigue el siguiente formato: buffer=handle.bulkRead(0x81,16) Cmo podemos ver, el mtodo bulkRead tambin necesita dos parmetros de entrada. El primero corresponde a la direccin del endpoint y el segundo al nmero de bytes que esperamos leer. Los endpoints a los que hemos ido haciendo referencia quedan definidos en el datasheet del fabricante y

tienen relacin con el protocolo de comunicacin USB. Toda conexin USB est formada por conexiones unidireccionales (conseguimos la bidireccionalidad ya que algunas son de entrada y otras de salida) y cada endpoint hace referencia a una de estas conexiones, cada una de ellas asociadas a su vez a una o varias funciones del dispositivo. La siguiente tabla muestra informacin ms detallada de los endpoints asociados al dispositivo USB4000 y sus funciones asociadas. ID 0x01 (OUT) 0x82 (IN) 0x86 (IN) 0x81 (IN) Funcin asociada Enviar instrucciones al dispositivos Adquisicin de datos espectromtricos (pxeles 1024-3840 y paquetes sync) Adquisicin de datos espectromtricos (pxeles 0-1023) Adquisicin del resto de datos (configuracin, etc.)

Por ejemplo, en el caso de querer acceder a los parmetros de configuracin (entre ellos el tiempo de integracin) debemos utilizar el mtodo bulkWrite con los parmetros 0x01 y 0xFE pasado a formato char, correspondiente el endpoint destinado al envo de comandos y al comando especfico para acceder al vector de configuracin respectivamente. Una vez realizada esta accin podemos leer los datos solicitados a travs del mtodo bulkRead. Sus parmetros de entrada corresponden al endpoint a utilizar para acceder a los datos de configuracin (0x81) y el valor 16 (se puede poner el valor directamente, no hace falta que sea una variable) que corresponde al numero de bytes que esperamos leer. Recordar que al realizar cualquier lectura se deben leer todos sus bits (aunque no los utilicemos), de lo contrario esos bits se quedaran en el buffer y har que el dispositivo no acepte ninguna otra accin de lectura y/o escritura.

3.3 MODIFICACIN DEL TIEMPO DE ADQUISICIN


El tiempo de adquisicin es un parmetro de configuracin del dispositivo USB4000 estrechamente relacionado con el valor de los datos a obtener (amplitud). Este tiempo nos determina el tiempo en que cada uno de los fotodiodos internos del dispositivo (fotodetectores) va estar expuesto a la luz incidente haciendo que la amplitud del los datos espectromtricos obtenidos sea directamente proporcional el tiempo de adquisicin configurado. En el software desarrollado se ha realizado un pequea prueba de testeo para comprobar la correcta modificacin de ste valor en el registro interno del dispositivo USB. El valor del tiempo de integracin se encuentra dentro del vector de estado (o Status segn el datasheet). Podemos obtener este vector (asignado a la variable buffer) a travs del siguiente cdigo: tosend=chr(0xfe) o=handle.bulkWrite(0x01,tosend) buffer=handle.bulkRead(0x81,16) print buffer La variable buffer presentar un aspecto similar al vector de estado siguiente, dnde los bytes 2 al 5 son los valores correspondientes al tiempo de integracin: (0, 15, 80, -61, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, -128, 85) En la siguiente tabla se detallan los bytes referentes al tiempo de integracin obtenidos en el vector de estado de ejemplo y su correspondiente interpretacin:

Byte #2 Valor obtenido Byte tiempo de integracin Binario(Ca2) 80 LSW-MSB 01010000

Byte #3 -61 LSW-MSB 11000011

Byte #4 0 MSW-LSW 00000000

Byte #5 0 MSW-MSB 00000000

Tiempo de integracin= 00000000 00000000 11000011 01010000 = 50.000s Podemos ver que el tiempo de integracin configurado actualmente en el dispositivo es de 50.000s. Este valor corresponde a la configuracin en una adquisicin anterior (el dispositivo conserva el tiempo de integracin de la ltima adquisicin realizada an habiendo desconectado el dispositivo). En la tabla del datasheet referente al Query Status se detalla el significado de los 16 bytes de configuracin. La lectura del vector de estado se realiza antes y despus de la modificacin del tiempo de integracin para comprobar su correcta modificacin. Para poder hacer la modificacin del tiempo de integracin debemos seguir el formato del comentado anteriormente tal y como ilustra la siguiente lnea de cdigo, dnde 0x01 corresponde al endpoint de envo de comandos y buf_tx al tiempo de integracin en el formato especificado por el fabricante: handle.bulkWrite(0x01,buf_tx) Cmo ya hemos dejado entrever, al valor correspondiente al tiempo de integracin, se le debe aplicar una reordenacin de bytes, tal y cmo indica el datasheet del dispositivo. El formato debe ser el siguiente: FORMATO ESPECIFICADO POR EL FABRICANTE Byte 0 0x02 Byte 1 LSW-LSB Byte 0 MSW-MSB Byte 2 LSW-MSB Byte 1 MSW-LSB Byte 3 MSW-LSB Byte 2 LSW-MSB Byte 4 MSW-MSB Byte 3 LSW-LSB

FORMAT INT (formato de partida)

Para realizar esta ordenacin, primero debemos pasar el valor int del tiempo de integracin ( itime) a binario (vector) y reordenar los bytes a posteriori. vector=[] while itime != 0: number=itime-((itime/2)*2) vector.append(number) itime = itime/2 vector = vector + ([0]*(32-len(vector))) vector.reverse() def elevat(x):return 2**x pot1=map(elevat,range(0,8)*4) pot1.reverse() buf=[vector[i]*pot1[i] for i in range (len(vector))] def sum(seq): def add(x,y):return x+y return reduce(add,seq,0) MSW_MSB=sum(buf[0:8])#Byte 4

MSB_LSB=sum(buf[8:16])#Byte 3 LSW_MSB=sum(buf[16:24])#Byte 2 LSW_LSB=sum(buf[24:32])#Byte 1 Con lo cual, la cadena a enviar es la concatenacin (suma) de los bytes (MSW_MSB, MSB_LSB, LSW_MSB y LSW_LSB) en el orden correspondiente, tal y cmo se indica a continuacin: buf_tx=chr(0x02)+chr(LSW_LSB)+chr(LSW_MSB)+chr(MSB_LSB)+chr(MSW_MSB) Seguidamente podemos enviar ya el tiempo de integracin con el debido formato (buf_tx) y comprobar cmo han quedado guardados los bytes en la cadena de configuracin, cmo hemos ya comentado. Aunque el tiempo de integracin nuevo sea igual al almacenado en memoria lo sobreescribiremos, ya que es ms rpido y eficaz que hacer las pertinentes comprobaciones.

3.4 LECTURA DE DATOS ESPECTROMTRICOS Y SU REPRESENTACIN GRFICA


El primer paso para llevar a cabo cualquier accin, cmo ya hemos ido repitiendo, es enviar el comando de la accin a llevar a cabo a travs del endpoint 0x01 (cmo en todas los comandos). En el caso de la adquisicin de datos espectromtricos el cdigo del comando tiene el identificador 0x09. buffer=chr(0x09) o=handle.bulkWrite(0x01,buffer) Posteriormente podemos hacer ya la adquisicin de los datos espectromtricos teniendo en cuenta que los datos espectromtricos a recibir tienen el siguiente formato: # PAQUETE 0 1 2 3 4 5 ... 14 15 END POINT EP6In (0x86) EP6In (0x86) EP6In (0x86) EP6In (0x86) EP2In (0x82) EP2In (0x82) EP2In (0x82) EP2In (0x82) EP2In (0x82) # BYTES 512 512 512 512 512 512 512 512 1 PXELES 0-255 256-511 512-767 768-1023 1024-1279 1280-1535 ... 3584-3840 Sync Packet

Las lneas de cdigo correspondientes a su adquisicin son: b0=handle.bulkRead(0x86,512) b1=handle.bulkRead(0x86,512) b2=handle.bulkRead(0x86,512) b3=handle.bulkRead(0x86,512) b4=handle.bulkRead(0x82,512) b5=handle.bulkRead(0x82,512) b6=handle.bulkRead(0x82,512) b7=handle.bulkRead(0x82,512) b8=handle.bulkRead(0x82,512) b9=handle.bulkRead(0x82,512) b10=handle.bulkRead(0x82,512) b11=handle.bulkRead(0x82,512) b12=handle.bulkRead(0x82,512) b13=handle.bulkRead(0x82,512)

b14=handle.bulkRead(0x82,512) sincro=handle.bulkRead(0x82,1) Es posible (y recomendable) juntar en un sola variable los datos adquiridos a travs del mismo endpoint, aunque en el cdigo anterior se ha desglosado para ver su equivalencia con la tabla de formato de los datos. No todos los datos adquiridos son informacin vlida, pero todos deben ser ledos por el buen funcionamiento del dispositivo. La informacin a desechar corresponde a la variable sincro que contiene informacin de sincronizacin, con lo que los datos de inters son: datos=b0 + b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9 + b10 + b11 + b12 + b13 + b14 Cmo ya hemos comentado con anterioridad, en los datos recibidos del espectrmetro (datos) cada valor est dividido en 2 bytes que para poder ser debidamente representados deben ser juntados en un slo valor equivalente. dades_LSB=[dades[2*i] for i in range(len(dades)/2)] dades_MSB=[dades[2*i+1]*256 for i in range(len(dades)/2)] lectura=[dades_LSB[i]+dades_MSB[i] for i in range(len(dades_LSB))] Para comprobar la correccin de los datos obtenidos con el debido formato (lectura) realizaremos su representacin grfica a travs de unos sencillos mtodos del mdulo pylab (traduccin de mtodos de Matlab para Python). En el prximo apartado comentaremos algunos de los resultados grficos obtenidos.

4 EJEMPLO PRCTICO DE FUNCIONAMIENTO


En el siguiente apartado mostramos los resultados grficos obtenidos a partir de diferentes tiempos de integracin, con lo que demostraremos la estrecha relacin entre este valor y la amplitud de los datos obtenidos. El conjunto de los resultados grficos nos servir para verificar de una forma visual, el correcto funcionamiento del sistema. Tambin se adjunta dos capturas hechas en dos momentos de ejecucin del programa en las que se puede observar los mensajes de control (Found y el vector estado), comentados en apartados anteriores.

Momento de la ejecucin en que el programa espera la introduccin del tiempo de integracin

Fin de la ejecucin, despus de representacin grfica de los datos obtenidos

Los resultados obtenidos para tiempo de integracin de 5.000, 10.000, 50.000, 100.000, 200.000 y 500.000s se muestran a continuacin:

Tiempo de integracin de 5.000 s

Tiempo de integracin de 10.000 s

Tiempo de integracin de 50.000 s

Tiempo de integracin de 100.000 s

Tiempo de integracin de 200.000 s

Tiempo de integracin de 500.000 s

En algn caso no se puede apreciar el crecimiento proporcional con el tiempo de integracin debido a la diferencia de escala entre los grficos. Los que si se puede observar claramente es la signatura espectral caracterstica de una luz procedente de un fluorescente. Tambin podemos observar que algunos picos de las ltimas adquisiciones quedan recortados, esto de debe a que los fotodetectores llegan a valores de luz incidente mayores al que pueden cuantificar ( un valor mximo de 32000 en la configuracin por defecto). Con estas comprobaciones consideramos que el sistema funciona correctamente.

5 LIBRERA OOS4000.py
A partir del programa anterior se ha realizado la librera Python del dispositivo USB4000 (OOS4000.py) con las cuatro funciones bsicas de cualquier adquisicin:

OpenDevice: establecer la comunicacin con el dispositivo a travs de su idVendor. ResetDevice: resetear el dispositivo. SentIntTime: configurar el tiempo de integracin del dispositivo. GetSample: adquirir datos espectromtricos representables grficamente.

6 BIBLIOGRAFA
[1] USB access module. <http://wiki.erazor-zone.de/wiki:projects:python:pyusb:pydoc > [2] USB4000 Data Sheet.<http://www.oceanoptics.com/technical/engineering/USB4000 OEM Data Sheet.pdf >

S-ar putea să vă placă și