Instituto Politécnico Nacional Unidad Profesional Interdisciplinaria en Ingeniería y Tecnologías Avanzadas Reporte final del proyecto: Diseño de una Interfaz Entre un Sensor de Imágenes CMOS y Dispositivos de Lógica Programable para Procesamiento de Imágenes en Tiempo Real Registro asignado por la SIP: 20071559 Director del Proyecto de Investigación: Victor Hugo Ponce Ponce (UPIITA-IPN) Profesores participantes: 1. Juan Antonio Jaramillo Gómez (UPIITA-IPN) 2. Herón Molina Lozano (UPIITA-IPN) 3. Isaac Guzmán Domínguez (UPIITA-IPN) Alumno participante: Oscar Manuel Rojas Padilla (UPIITA-IPN) Introducción El desarrollo de sistemas de procesamiento de imágenes en tiempo real es una tarea que se requiere a nivel laboratorio y a nivel industrial. Por lo que es necesario contar con una infraestructura que permita realizar tareas como lo son: 1. Captura de imágenes con restricción de tiempo 2. Procesamiento de imágenes 3. Reconocimiento de patrones 4. Realización de acciones de control basadas en las imágenes que se capturan De manera tradicional para realizar la captura de imágenes se puede realizar por medio de cámaras de video con tecnología de Dispositivos de Carga Acoplados (Charge Couple DevicesCCD por sus siglas en Inglés). Sin embargo este tipo de cámaras está llegando a sus límites tecnológicos, esto es, se pueden llegar a capturas hasta decenas de imágenes por segundo. Otro tipo de tecnología que actualmente está teniendo mucho auge es la relacionada con cámaras de video que utilizan transistores CMOS (Complemented Metal-Oxide Semiconductor). El número de imágenes que se ha llegado a capturar es de 1000 imágenes por segundo. Por lo que es necesario para el desarrollo del país incursionar en este tipo de tecnologías. Métodos y Materiales Para el manejo de las cámaras CMOS es necesario realizarlo con sistemas digitales que permitan manejar con restricción de tiempos, esto es en tiempo real. Por lo que se propuso implementar este tipo de sistema utilizando Arreglos de Compuertas Programables en Campo (Field Programable Gate Arrays FPGA’s), utilizando programación en VHDL, que es un estilo de programación estandar para la programación de FPGA’s. Se utilizó una tarjeta Spartan 3E de la compañía Digilen que utliza un FPGA de la compañía Xilinx. El C.I. que se utilizó es el FGG320A. El siguiente reporte presenta las actividades realizadas en relación al proyecto. Diagrama a cuadros del sistema Se presenta a continuación el diagrama a cuadros del sistema completo. Imagen 480 X 640 X 3 Serial Bus 1 bit Registro de corrimiento universal de 16 bits Preset = 0x01 MSB Bus 16 bits Latch de 16 bits Triple estado clk Mux 16,2 Desborde clk Contador de 12 bits Bus 12 bits (ADRES) Bus 16 bits (DATA) Contador de 4 bits con bit de desborde y Preset = 0x01 Bus 4 bit RAM Latch de 16 bits Triple estado Bus 16 bits Registro de corrimiento universal de 16 bits Clk_div Bus 1 bit Div de reloj Funciones para impresión en pantalla * Sinc H * Sinc V * RGB Display La idea básica consiste en utilizar una cámara CMOS de 680 por 480 pixeles. La cámara envía la imagen a un registro de corrimiento de 16 bits en donde cada píxel es capturado y posteriormente enviada a un match también de 16 bits y a un multiplexor de 16 por 2. Del latch de 16 bits se envía la información de cada píxel a una memoria RAM de 16 bits. Para ir acceder a cada dirección de la memoria se utiliza un contador de 12 bits, con lo que pueden guardarse hasta 4096 bits. Posteriormente, se utilizará un controlador que permite enviar cada píxel a un monitor tipo CGA. A continuación se presenta los resultados obtenidos con el controlador de la pantalla. Para comenzar a recobrar las imágenes se utilizó de manera momentánea una computadora. La computadora utiliza una cámara de video. Y posteriormente se utilizó el puerto USB para el envío de datos a la tarjeta Spartan 3E. Resultados Control de una pantalla VGA mediante una tarjeta “Espartan 3E” Fundamentos teóricos La tarjeta E3 dispone de un conector DB15 cableado a puertos de la FPGA. Dicho conector permite la conexión con la pantalla del PC utilizando un cable estándar VGA. La conexión entre la FPGA utilizará cinco puertos: HS (sincronismo horizontal), VS (sincronismo vertical), R (rojo), G (verde) y B (azul). Teóricamente, Las señales de color (R, G y B) son analógicas y determinan la intensidad de color de cada píxel. Sin embargo, en la placa están conectadas a un puerto digital (entre 0 y 3.3V) a través de una resistencia de 270Ω. Al estar el cable VGA terminado a 75Ω, un ‘1’ en la FPGA fijará una señal de 0.7V (máxima intensidad de color) y un ‘0’ será 0V. Por tanto, tendremos sólo dos niveles por color, pudiendo representar hasta 8 colores como se muestra. Monitor VGA en modo 640x480 En este apartado se explicará cómo deben generarse las señales HS, VS, R, G y B para representar una imagen en un monitor en modo 60Hz, 640x480 y 8 colores. Es decir. Para explicar el protocolo VGA es necesario conocer el funcionamiento básico de un Tubo de Rayos Catódicos (CRT) Tres cañones de electrones producen tres haces de electrones, uno por cada color básico (rojo, azul y verde). Estos haces de electrones se focalizan, utilizando una bobina, para conseguir que converjan en un punto de la pantalla. Posteriormente, mediante un campo magnético generado por un par de bobinas (horizontal y vertical) se direccionan al punto deseado de la pantalla. En la pantalla de visualización, los rayos son separados por una máscara e inciden en una capa fosforescente con zonas receptivas para cada color. Por otro lado, la intensidad luminosa dependerá de la potencia a la que se emite el haz de electrones, controlable mediante las señales analógicas R, G y B. Se representarán imágenes en pantalla haciendo que el haz de electrones la recorra en una sucesión de líneas (de izquierda a derecha) comenzando por la esquina superior izquierda. La onda en forma de diente de sierra representa la corriente que pasa por la bobina que crea que campo magnético para la deflexión horizontal. Se puede comprobar, que se representa la imagen (Horizontal display time) cuando el haz de electrones va de izquierda a derecha y está apuntando correctamente a la pantalla, existiendo un tiempo (retrace time) para que el cañón vuelva al comienzo de la siguiente línea. El pulso de sincronismo vertical (HS) marca el instante en que el cañón debe comenzar una nueva línea, pudiendo distinguir un tiempo anterior (“front porch”) en que el cañón está apuntando fuera de la pantalla y un tiempo posterior (“pack porch”) necesario para que el haz se posicione en el inicio de la siguiente línea. Es importante que durante todo el “retrace time” los cañones de electrones estén apagados. La frecuencia a la que se proporcionan los pulsos de sincronismos vertical y horizontal determina la velocidad y el número de veces que el haz de electrones recorre la pantalla. De esta forma seleccionamos la resolución de visualización de la imagen en el monitor. El estándar VGA admite diferentes soluciones, para las que tendríamos que utilizar diferentes frecuencias en HS y VS. Funcionamiento del programa de control de VGA Se realizó un programa en VHDL que recibe una señal de tres bits genera el protocolo para la transmisión a la pantalla VGA y se transmite. Librerías del programa library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Declaración de señales, constantes entity vga is port ( clk: in std_logic; Video : in std_logic_vector (1 downto 0); shor, sver : out std_logic; RGB : out std_logic_vector (2 downto 0)); end vga; architecture Arq_vga of vga is constant hpixels: std_logic_vector(9 downto 0) := "1100100000"; --Valor de pixeles en linea horizontal (800) constant vlines: std_logic_vector(9 downto 0) := "1000001001"; --Numero de lineas horizontales en pantalla (521) constant hbp: std_logic_vector(9 downto 0) := "0010010000"; --Limite horizontal inferior (144) constant hfp: std_logic_vector(9 downto 0) := "1100010000"; --Limite horizontal superior (784) constant vbp: std_logic_vector(9 downto 0) := "0000011111"; --Limite vertical inferior ( 31) constant vfp: std_logic_vector(9 downto 0) := "0111111111"; --Limite vertical superior (511) signal conh: std_logic_vector(9 downto 0) := (others=>'0'); --Contadores horizontal signal conv: std_logic_vector(9 downto 0) := (others=>'0'); --Contador vertical signal clkdiv: std_logic := '0'; --Señal de reloj de 25MHz signal vidon: std_logic := '0'; --Permite establecer la habilitación para la señal de video signal vsenable: std_logic := '0'; --Habilita el contador vertical begin Divisor de reloj para que coincida con el del monitor VGA, de 50 MHz a 25MHz. process(clk) begin if(clk = '1' and clk'event) then clkdiv <= not clkdiv; end if; end process; Contador horizontal process(clkdiv) begin if(clkdiv = '1' and clkdiv'event) then if conh = hpixels then --Numero de pixeles en linea horizontal conh <= (others=>'0'); --Resetea el contador vsenable <= '1'; --Habilita el contador vertical else conh <= conh + 1; --Incrementa el contador horizontal vsenable <= '0'; --Deshabilita el contador vertical end if; end if; end process; Pulso de sincronia horizontal shor <= '1' when conh(9 downto 7) = "000" else '0'; Contador vertical process(clkdiv) begin if(clkdiv = '1' and clkdiv'event and vsenable = '1') then if conv = vlines then --Numero de lineas verticales conv <= (others=>'0'); --Resetea el contador else conv <= conv + 1; --Incrementa el contador vertical end if; end if; end process; Pulso de soncronía vertical sver <= '1' when conv(9 downto 1) = "000000000" else '0'; Transmision de pixceles RGB <= Video when (conh > hbp and conh < hbp and conv > vbp and conv < vbp and vidon ='1') else "000"; Habilita la señal de video solo en los margenes de visualizacón vidon <= '1' when (((conh > hbp) and (conh < hfp)) or ((conv > vbp) and (conv < vfp))) else '0'; Fin del Programa end Arq_vga; Dispositivo USB Actualmente en el mercado existen diversos dispositivos programables a diferentes niveles que nos proporcionan la interfaz a una PC por medio del puerto USB, dejando atrás a los puertos paralelo y serial, estos dispositivos son más versátiles, es por eso que su producción y popularización se vuelve más grande cada día, y es por esto mismo que elegimos uno de estos dispositivos para el proyecto que se realizó. Para elegir adecuadamente el dispositivo que a utilizar en esta etapa del proyecto, fue necesario el comprender en buena parte el protocolo de comunicación del puerto USB, una vez que se observaron y analizaron cada una de las aplicaciones y los recursos que este protocolo podía entregar se optó por la búsqueda de dispositivos que funcionarán como un dispositivo esclavo, el cual es reconocido por el HOST y este le asigna una dirección a la cual le enviará los datos de lectura o escritura, según sea el caso. La razón de elegir un dispositivo que funcione como esclavo y no como HOST, fue el hecho de realizar pruebas de envío y recepción de imágenes a través de la PC hacia el FPGA Spartan-3E, por medio de la interfaz que se desarrolló; y no de forma independiente, como de una cámara directamente hacia el FPGA, donde el uso de la PC podría quedar atrás y únicamente se necesitaría la interfaz entre estos dos. El dispositivo programable que se seleccionó, el micro controlador PIC18F4550, cuenta con el modulo USB apropiado, ya que funciona con el protocolo USB 2.0, con una velocidad de transmisión de 12MB/s, es decir la Full speed de ese mismo protocolo.(Para más detalles ver ANEXO 1) PIN out del PIC18F4550 Interfaz USB Software del Microcontrolador Una vez elegido el dispositivo que se empleará, en función de su arquitectura tendremos que ver la configuración que nos conviene utilizar, es decir los puertos, módulos, etc., así como el uso de la memoria disponible. Este microcontrolador cuenta con cinco puertos de comunicación, puerto A, puerto B, puerto C, puerto D y puerto E; de los cuales, por el momento utilizamos el puerto B, por la versatilidad que ofrece tanto en el acomodo de los pines, como en la cantidad de bites que puede transmitir, ocho para ser precisos, los necesarios para un protocolo de puerto paralelo mismo que maneja el FPGA Spartan-3E, además de que las funciones secundarias que este posee no nos serán de interés, hacen del puerto B de este micro controlador la mejor opción para el trabajo. El funcionamiento de la interfaz USB de este dispositivo, es fácil de controlar y configurar gracias a que los fabricantes ya han dispuesto, al igual que los de otros dispositivos similares, las bibliotecas y controladores necesarios para la configuración de estos módulos, ya sea que funcionen como dispositivos esclavos o maestros. Es de esta manera en la que al iniciar con la programación del PIC18F4550, lo primero que se hace es incluir la biblioteca del controlador del dispositivo y posteriormente la que controla el modulo del USB en cualquier forma, inclusive hay algunas aplicaciones que nos ayudan a configurar el puerto de salida de los datos. En el ANEXO 2 se puede encontrar el código del programa principal en lenguaje ensamblador, para hacer que el PIC reciba los datos de la PC en mediante el puerto USB y posteriormente los convierta a 8 bits (paralelo), para que a su vez los mande a través del puerto B hacia otro dispositivo. Driver Para poder lograr una comunicación exitosa entre la PC y el PIC, se debe de generar un driver o controlador, esto es necesario, pues cuando se conecta el hardware a la PC, se activa una interrupción más en la lista de dispositivos externos e inmediatamente esta buscará dentro de una lista de controladores cual es el requerido por el sistema, aunque existen controladores genéricos, como los son para mouse, teclados o dispositivos de almacenamiento externo, el dispositivo que nosotros hemos desarrollado no cumple con ninguna de estas características, por lo que se vio la necesidad de generar un controlador especifico para él. La función de este controlador será una vez que halla sido reconocido el dispositivo por el sistema operativo, crear dentro de la lista de puertos de comunicación serial (RS-232), un puerto nuevo, conocido como COM4, el cuatro fue escogido ya que ninguna computadora actual tiene más de dos puertos de este tipo. Es mediante este puerto serie virtual, del que enviaremos datos hacia nuestro sistema. Ir al ANEXO 3 para ver el controlador generado. Hardware Una vez concluido y descargado el programa en el dispositivo, se procedió a la elaboración de la tarjeta mediante la cual se comunicaría la PC hacia la tarjeta del FPGA. Para la elaboración de esta, solo se necesitó tomar en cuenta la arquitectura del PIC y la configuración que se había elegido para el proyecto, quedando el diagrama de la tarjeta de la siguiente forma: Tarjeta de la primera etapa Diagrama del circuito impreso de la primer etapa de la interfaz Sin embargo, existe una diferencia de voltaje, la PC y el micro controlador trabajan a 5 volts, ese mismo voltaje está presente en el puerto USB, así como en los puertos de entrada y salida del PIC; y el FPGA trabaja con un voltaje máximo de 3.3 volts, esto nos lleva a la implementación de una segunda etapa en el hardware de la interfaz, la de acoplamiento de voltaje en los puertos. Para dicha etapa, se eligieron los circuitos integrados MC14504B, llamados transceiver, que nos ofrecen la conversión de voltaje de entrada a uno diferente de salida, debidamente referenciado en el mismo CI. A continuación, se muestra es esquemático del hardware, tal y como queda añadiéndole esta segunda etapa. Diagrama final del hardware de la interfaz En el diagrama se puede apreciar que la etapa de acoplamiento de voltaje se conforma por dos pastillas de los mencionados circuitos, de los cuales uno recibe las primeras seis líneas de información y el segundo las dos restantes, esto se debe a que dichos CI no tienen la capacidad de cambio de voltaje a más líneas y no hay alguno otro de la misma familia que las tenga, existe un dispositivo ideal para este trabajo, el 74LVC4245, desgraciadamente este tipo de dispositivos no existen en nuestro país. A la salida podemos encontrar que nuevamente las líneas de las dos pastillas, pertenecientes al bus de datos, se unen en el puerto que bien puede ser un simple conector, como puede ser un cable que conecte directamente al FPGA. 2ª etapa, convertidores de voltaje También se puede apreciar el conector USB tipo B hembra, el cual es casi por normalización que se ponga como entrada a un dispositivo de este tipo. El cable que conectara al dicho dispositivo con la computadora, HOST, también se encuentra estandarizado, cuenta con una entrada tipo A y una tipo B ambos extremos son machos, tal y como se ilustra a continuación. Extremos de un cable USB A-B y sus respectivos pines Número de Pin 1 2 3 4 Color Función Rojo Blanco Verde Negro V5volts D D+ GND Prueba del hardware y controlador Una vez terminado el diseño del hardware y montaje del mismo en una tablilla de pruebas, procedimos a las prueba del hardware desarrollado con el fin de encontrar errores antes de hacer las placas del circuito impreso y de encontrar posibles errores en el software generado como controlador. Sistema montado en una tablilla de pruebas Estando ya validados el circuito y controlador, se realizó la placa del circuito impreso mencionada y procedimos a la conexión del sistema a la PC, la cual reconoce al nuevo hardware e indica que no existen controladores disponibles para el mismo. Conexión a la PC para su prueba El sistema solicita que se instale el controlador del nuevo hardware, ya sea mediante búsqueda automática o manual. Una vez localizado el nuevo controlador, se instala en la PC. Y de inmediato en la lista del administrador de dispositivos aparecerá el nuevo puerto de comunicaciones, COM4. En la imagen de la izq. podemos observar que la PC solo tiene un COM, en la imagen de la derecha aparece COM3 Una vez obtenido dicho este puerto adicional en la lista quedan probados el Hardware, hasta la primera etapa, y el controlador mismo. La siguiente prueba consiste en verificar que realmente se esté generando la comunicación entre la PC y el PIC, y que este último proporcione mediante su puerto B los ocho bits de datos enviados via USB desde la PC. Para esta etapa fue necesario el desarrollar un programa en MATLAB, que enviara a dicho puerto una serie de pulsos, los que se visualizará, en una barra de leds, dispuesta en paralelo a la etapa de conversión de voltaje. Barra de leds que permitió observar la transmisión de datos por el Puerto del PIC hacia los transceivers El programa desarrollado es un contados simple de ocho bits, que ira de 0 a 255, con su respectiva equivalencia en binario, una vez terminado el conteo quedará probado que las ocho vías del bus de datos funciona correctamente. Ir al ANEXO 4 para ver el programa del contador de ocho bits. Finalmente, la última etapa de prueba consta de la segunda parte del hardware, la etapa de conversión o acoplamiento de voltaje. Para probar esta parte del sistema, únicamente es necesario alimentar el circuito con una fuente que proporcione como máximo 3.3 volts y medir el voltaje en cada una de las vías del bus de datos que va hacia el FPGA. Es importante que dicho voltaje no presente mucha variación y que este lo mas próximo a 3 volts, de lo contrario el FPGA podría sufrir daños en el puerto de entrada. Impacto 1. Ganar experiencia en el manejo de imágenes CMOS utilizando FPGA’s. 2. Dar un curso intersemestral para profesores. 3. Obtener un manual de usuarios. 4. Dar experiencia en desarrollo de proyecto a un alumno PIFI y un alumno de Servicio Social. 5. Exponer un artículo en un congreso nacional. ANEXO 1 ANEXO 2 Programa realizado en PICBASIC PRO(TM) Compiler 2.47 para el control de flujo de datos entre el PIC18F4550 y una PC, vía USB. INCLUDE "C:\PBP\18F4550.INC" ; En la sección siguiente se definen las variables para uso de memoria RAM interna #define RAM_START RAM_END RAM_BANKS BANK0_START BANK0_END BANK1_START BANK1_END BANK2_START BANK2_END BANK3_START BANK3_END BANKA_START BANKA_END OSC 48 EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU 00000h 003FFh 00004h 00060h 000FFh 00100h 001FFh 00200h 002FFh 00300h 003FFh 00000h 0005Fh ; En esta sección se definen los registros para el uso de memoria y otros generales FLAGS EQU RAM_START + 000h R0 EQU RAM_START + 001h R1 EQU RAM_START + 003h R2 EQU RAM_START + 005h R3 EQU RAM_START + 007h R4 EQU RAM_START + 009h R5 EQU RAM_START + 00Bh R6 EQU RAM_START + 00Dh R7 EQU RAM_START + 00Fh R8 EQU RAM_START + 011h GOP EQU RAM_START + 013h RM1 EQU RAM_START + 014h RM2 EQU RAM_START + 015h RR1 EQU RAM_START + 016h RR2 EQU RAM_START + 017h RS1 EQU RAM_START + 018h RS2 EQU RAM_START + 019h _buffer EQU RAM_START + 01Ah _cnt EQU RAM_START + 01Bh _PORTL EQU PORTB _PORTH EQU PORTC _TRISL EQU TRISB _TRISH EQU TRISC ; Inicio del programa principal INCLUDE "USBCDC.MAC" ; agrega la biblioteca del controlador USB INCLUDE "C:\PBP\PBPUSB18.LIB" ; agrega la biblioteca del bus de salida ; Inicialización de puertos MOVE CB 000h, TRISB MOVE CB 000h, PORTB MOVE CB 0FFh, TRISD USBINIT ;rutina de entrada de datos via USB LABEL _idleloop USBSERVICE ; recepción de datos MOVE CB 001h, _cnt USBIN CBBL 003h, _buffer, _cnt, _idleloop ; decodifica la información MOVE BB _buffer, PORTB ; envía el Nuevo paquete de datos al buffer MOVE CB 000h, _buffer ; escribe en el Puerto B la info del buffer END ANEXO 3 Programa del controlador del dispositivo USB que simula un puerto RS-232, para una plataforma Windows 2000 y posteriores. ; Windows USB CDC ACM Setup File ; Copyright (c) 2000 Microsoft Corporation ; Copyright (C) 2004 Microchip Technology Inc. [Version] Signature="$Windows NT$" Class=Ports ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} Provider=%melabs% LayoutFile=layout.inf DriverVer=08/17/2001,5.1.2600.0 [Manufacturer] %MFGNAME%=DeviceList [DestinationDirs] DefaultDestDir=12 ; 12 means "C:\Windows\system32\drivers" [SourceDisksFiles] [SourceDisksNames] [DeviceList] %DESCRIPTION%=DriverInstall, USB\VID_04D8&PID_000A descriptor ; Note VID, PID match device ;-----------------------------------------------------------------------------; Windows 2000/XP Sections ;-----------------------------------------------------------------------------[DriverInstall.nt] CopyFiles=DriverCopyFiles AddReg=DriverInstall.nt.AddReg [DriverCopyFiles] usbser.sys,,,0x20 ; 0x20 means "Don't overwrite a newer version" [DriverInstall.nt.AddReg] HKR,,DevLoader,,*ntkern HKR,,NTMPDriver,,usbser.sys HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" [DriverInstall.nt.Services] AddService=usbser, 0x00000002, DriverService ;0x02 means "Mark this as driver for this device" [DriverService] DisplayName=%SERVICE% ServiceType=1 StartType=3 ErrorControl=1 ServiceBinary=%12%\usbser.sys ; %12% means "C:\Windows\system32\drivers" ;-----------------------------------------------------------------------------; String Definitions ;-----------------------------------------------------------------------------[Strings] melabs="microEngineering Labs, Inc." MFGNAME="microEngineering Labs, Inc." DESCRIPTION="PBPCDC Communications Port" SERVICE="PBP RS-232 Emulation Driver" ANEXO 4 Programa desarrollado en MATLAB del contador para la prueba del sistema hasta la primer etapa del hardware. %clear all; close all;clc pto=serial('COM4'); %Crea la entidad del puerto COMx fopen(pto); %Abre el puerto for cont=0:1:255 %Ciclo de escritura de 0 a 255 fprintf(pto,cont); %Escribe en el puerto el valor % pause(.5) ; %Retardo de medio segundo cont=cont+1; %Incrementa el contador end fclose(pto);