150
DISEÑO Y REALIZACIÓN DE UN SISTEMA ON BOARD DIAGNOSTICS (OBD-II) ALUMNO: OSCAR RAYO MANSILLA DIRECTOR: JORDI SELLARÈS GONZÁLEZ 4 DE JUNIO DE 2009

ProjecteOscar-memoria

Embed Size (px)

Citation preview

Page 1: ProjecteOscar-memoria

DISEÑO Y REALIZACIÓN DE UN SISTEMA

ON BOARD DIAGNOSTICS (OBD-II)

ALUMNO: OSCAR RAYO MANSILLA

DIRECTOR: JORDI SELLARÈS GONZÁLEZ

4 DE JUNIO DE 2009

Page 2: ProjecteOscar-memoria

2

Page 3: ProjecteOscar-memoria

3

ÍNDICE

1. Introducción 5

1.1. Justificación del proyecto…………………………………………5

1.2. Antecedentes…………………………………………………………..6

1.3. Objetivos………………………………………………………………..10

1.4. Alcance del proyecto………………………………………………11

1.5. Descripción general del proyecto……………………………12

1.5.1. Descripción básica del hardware……………..12

1.5.2. Descripción básica del software………….…..13

2. Diseños realizados 14

2.1. Metodología utilizada……………………………………………14

2.2. Recursos utilizados………………………………………………..16

2.3. Descripción del diseño del modem interface………….21

2.4. Descripción del diseño del programador JDM2…......25

2.5. Modificaciones del diseño del modem…………………..29

2.6. Diseño de la aplicación de prueba en C++………………37

2.7. Diseño de la aplicación de prueba en JAVA…………….40

2.8. Diseño de la aplicación gráfica diseñada en JAVA.....46

Page 4: ProjecteOscar-memoria

4

3. Resultados 52

3.1. Ámbito de utilización…………………………………………….52

3.2. Validación de los diseños……………………………………….52

3.3. Descripción del funcionamiento…………………………….54

3.4. Aplicaciones del proyecto………………………………………66

4. Comentarios finales 67

4.1. Plan de trabajo……………………………………………………………67

4.2. Lista de materiales………………………………………………………68

4.3. Presupuesto………………………………………………………………..70

4.4. Objetivos logrados………………………………………………………71

4.5. Conclusiones……………………………………………………………….71

4.6. Mejoras futuras…………………………………………………………..72

5. Bibliografía 73

6. Anexo 74

Page 5: ProjecteOscar-memoria

5

1. Introducción

1.1. Justificación del proyecto

La motivación principal de este proyecto es llegar a poder diseñar un sistema

con el que poder diagnosticar las posibles averías de cualquier vehículo sin

tener que recurrir a los costosos servicios oficiales.

Normalmente cuando se nos avería el coche siempre tenemos que acabar

recurriendo a los talleres de reparación de los cuales dispone el fabricante de

nuestro vehículo, y aunque desconocemos cuales son los medios de los que

disponen para diagnosticar la avería, si sabemos que existe un herramienta que

conectándola al vehículo averigua el problema al instante. Esto se debe a que

estas marcas tan famosas equipan nuestros coches con sistemas electrónicos

capaces de gestionar toda la mecánica y electricidad de que dispone, sin más

ayuda que la de un modulo electrónico.

En realidad estos módulos no son más que una pequeña computadora a la cual

si se conoce su funcionamiento se puede acceder aunque su fabricante intente

taparlo, cosa que no les es posible ya que desde hace ya bastantes años están

obligados a implementar un estándar de autodiagnóstico llamado “OBD-II”, que

se hizo público a consecuencia de las grandes emisiones contaminantes a las

que estamos expuestos, implantando así un mecanismo de control de estas.

Estos módulos son el objetivo de este proyecto, ya que en el momento que

podamos comunicarnos con ellos podremos saber que le ocurre a nuestro coche

y por tanto cuando tengamos que acudir al taller nosotros sabremos, en parte,

si nos están estafando, cosa que lamentablemente a veces pasa.

Page 6: ProjecteOscar-memoria

6

1.2. Antecedentes

OBD (On Board Diagnostics) es un sistema de diagnóstico a bordo en vehículos

(coches y camiones). Actualmente se emplea OBD-II (Estados Unidos), EOBD

(Europa), y JOBD (Japón) estándar que aportan un control casi completo del

motor y otros dispositivos del vehículo. OBD II es la abreviatura de On Board

Diagnostics (Diagnóstico de Abordo) II, la segunda generación de los

requerimientos del equipamiento autodiagnosticable de abordo de los Estados

Unidos de América. Las características de autodiagnóstico de a bordo están

incorporadas en el hardware y el software de la computadora de abordo de un

vehículo para monitorear prácticamente todos los componentes que pueden

afectar las emisiones. Cada componente es monitoreado por una rutina de

diagnóstico para verificar si está funcionando perfectamente. Si se detecta un

problema o una falla, el sistema de OBD II ilumina una lámpara de advertencia

en el cuadro de instrumentos para avisarle al conductor.

La lámpara de advertencia normalmente lleva la inscripción "Check Engine" o

"Service Engine Soon". El sistema también guarda informaciones importantes

sobre la falla detectada para que un mecánico pueda encontrar y resolver el

problema. En los Estados Unidos de América, todos los vehículos de pasajeros y

los camiones de gasolina y combustibles alternos a partir de 1996 deben contar

con sistemas de OBD II, al igual que todos los vehículos de pasajeros y camiones

de diesel a partir de 1997, en Europa a partir del año 2001 se obliga implantar el

estándar EOBD. Además, un pequeño número de vehículos de gas fueron

equipados con sistemas de OBD II.

Por tanto la pregunta ahora es, ¿qué fue OBD I?

OBD I fue la primera regulación de OBD que obligaba a los productores a

instalar un sistema de monitoreo de algunos de los componentes controladores

de emisiones en automóviles. Obligatorios en todos los vehículos a partir de

1991, los sistemas de OBD I no eran tan efectivos porque solamente

monitoreaban algunos de los componentes relacionados con las emisiones, y no

eran calibrados para un nivel específico de emisiones.

Y además, ¿qué es EOBD?

EOBD es la abreviatura de European On Board Diagnostics (Diagnóstico de a

Bordo Europeo), la variación europea de OBD II. Una de las diferencias es que

no se monitorean las evaporaciones del depósito. Sin embargo, EOBD es un

sistema mucho más sofisticado que OBD II ya que usa "mapas" de las entradas a

Page 7: ProjecteOscar-memoria

7

los sensores expectadas basados en las condiciones de operación del motor, y

los componentes se adaptan al sistema calibrándose empíricamente. Esto

significa que los repuestos necesitan ser de alta calidad y específicos para el

vehículo y modelo.

Todos los estándares antes mencionados implementan varios modos de trabajo,

es decir, según la parte de información a la que queramos acceder necesitamos

utilizar un modo diferente, dentro de cada uno de ellos podemos usar un

abanico de parámetros muy amplio.

Los modos de trabajo más extendidos son los siguientes:

Modo 01: Se utiliza para determinar qué información del modulo

electrónico (ECU) está a disposición de la herramienta de exploración.

Modo 02: Muestra los llamados en este contexto “Freeze Frame Data”, es

decir, capturas puntuales de información que ha ido almacenado la ECU.

Modo 03: Lista los posibles fallos producidos en la mecánica mediante

códigos de error identificativos (DTC).

Modo 04: Se utiliza para borrar los códigos de error almacenados (DTC) y

los datos “Freeze Frame Data”.

Modo 05: Muestra los valores tomados a los sensores de oxigeno y los

resultados de los test que les ha realizado de forma autónoma la ECU.

Modo 06: Se usa para obtener los resultados de los test realizados por la

ECU al sistema de monitoreo no continuo. Existe normalmente un valor

mínimo, máximo y actual de cada uno de los test.

Modo 07: Se usa para solicitar resultados al sistema de control

permanente. Este modo lo suelen utilizar los técnicos después de una

reparación del vehículo, y después de borrar la información de

diagnóstico para ver los resultados de las pruebas después de un solo

ciclo de conducción, determinando si la reparación ha solucionado el

problema.

Sólo hay tres monitores continuos identificados: combustible, fallo de

encendido, e integridad de los componentes.

En este proyecto solo se va ha hacer uso del modo 01, 03 y 04, aunque teniendo

en cuenta que el modo 01 dispone de más de 60 PID’s diferentes, no es poco el

trabajo a desarrollar.

Page 8: ProjecteOscar-memoria

8

Actualmente ya existen muchas herramientas y software disponible para poder

llevar a cabo la inspección de un vehículo dotado de OBD-II. Existen muchos

tipos de herramientas distintas, pero principalmente la gran diferencia entre

ellas es si pueden o no trabajar de forma autónoma, es decir, si necesitan o no

ser ejecutadas en un ordenador personal bajo un sistema operativo.

Como ejemplo podemos encontrarnos el software llamado ScanMaster, el cual

se puede utilizar de forma completa previo pago de una pequeña cantidad de

dinero:

Page 9: ProjecteOscar-memoria

9

También podemos encontrar el software ScanTool.net, el cual ha sido de mucha

utilidad para este proyecto ya que en una de sus versiones ofrece el código

fuente con el que fue diseñado:

Estos programas están diseñados para trabajar junto con el microcontrolador

ELM327, es decir, necesitan de este elemento intermedio entre el PC y el

vehículo. Existen en el mercado muchos modelos de interface disponibles en el

mercado, pero todas se basan en este micro. A continuación podemos ver

algunos ejemplos:

Interface ELM327

Page 10: ProjecteOscar-memoria

10

Interface ELM327 Interface ELM327 con Bluetooth

En las imágenes vemos que los modelos tienen diferentes formas y diferentes

métodos de conexión, ya que en uno de los casos se realiza por “bluetooth”,

pero su funcionamiento respecto al estándar OBD-II es idéntico.

1.3. Objetivos

Este proyecto abarca una pequeña parte del complejo campo de la

autodiagnosis en la automoción, y por tanto no pretende crear un sistema que

pueda substituir a las avanzadas herramientas de las que dispone cualquier

servicio de manteniendo, ya que el estándar OBD-II, aun siendo de libre acceso,

comprende modos de trabajo de los cuales no se tiene información en este

proyecto. Mucha de la documentación que engloba al OBD-II está disponible

previo pago a las respectivas empresas que lo han diseñado y estandarizado,

como es el caso de la Sociedad Americana de Ingenieros (SAE) o la Organización

Internacional para la Estandarización (ISO). Aun no disponiendo de toda la

información deseada los objetivos de este proyecto son bastante ambiciosos y

se pueden listar como sigue:

Conseguir una comunicación estable con cualquier centralita electrónica

(ECU) de cualquier vehículo equipado con OBD-II.

Conseguir desarrollar una aplicación portable a cualquier sistema

operativo y plataforma utilizando lenguaje JAVA y la estructura de

programación “por capas”.

Page 11: ProjecteOscar-memoria

11

Realizar mejoras en el hardware ya existente en el mercado a partir del

cual se construirá nuestra interface.

Demostrar que con la información disponible en la red, es posible

acceder a los sistemas de control que implementan los fabricantes de

automóviles en sus vehículos.

1.4. Alcance del proyecto

El alcance de este proyecto incluye la creación de un sistema que implementa

una parte de las grandes posibilidades que ofrece el OBD-II, pudiéndose usar

como una herramienta orientativa a la hora de diagnosticar una posible avería.

Este sistema utiliza por un lado un modem interface que adecua las señales

procedentes de la centralita electrónica que se encuentra en el vehículo (ECU), a

las señales que necesita un puerto USB de cualquier ordenador. A partir de aquí,

un software de control gestionara toda la información recibida. Muchos de los

métodos de diagnostico existentes utilizan este planteamiento pero ninguno de

ellos, por lo menos oficialmente, utiliza una aplicación desarrollada en JAVA

que, por lo tanto, permita ejecutarse en la mayoría de los sistemas operativos

existentes, incluyendo el famoso Linux y además en diferentes tipos de

plataformas.

Para desarrollar el hardware se utilizaran diseños de interfaces ya existentes a

partir de los cuales se creará la que se utilizara en este proyecto, es decir, se

recapitularan los esquemas eléctricos de los que se dispongan y sobre el PCB

elegido se añadirán las posibles mejoras que pudieran aportar otros diseños.

Esta parte del trabajo también conlleva la construcción y puesta en marcha de

un programador de microcontroladores, necesario para implementar el

firmware a partir del cual el micro utilizado en la interface funcionará.

Po otro lado el software ha desarrollar tiene un papel igual o más importante,

ya que para conseguir diseñar la aplicación de control sobre el modem

interface, se necesitan realizar los primeros programas de prueba que servirán

para constatar las bases del funcionamiento de la última y definitiva aplicación

que interactuará con el modem. Este último programa constará de diferentes

apartados y opciones en un entorno visual que mostrará los resultados de una

forma fácilmente comprensible dejando así todo el proceso de cálculo en

segundo plano.

Page 12: ProjecteOscar-memoria

12

1.5. Descripción general del proyecto

En este proyecto como se ha ido comentado a lo largo de este documento se

pretende elaborar un sistema capaz de comunicarse con la electrónica que

gestiona cualquiera de los vehículos dotados con el estándar OBD-II, y para

llevarlo acabo ha sido necesario trabajar sobre diferentes aspectos que están

involucrados en el proceso de comunicación. Por tanto principalmente existen

dos partes importantes a diferenciar en el desarrollo de este proyecto:

La parte que engloba el hardware necesario, que nos es más que un

modem interface que hace de intérprete entre la centralita electrónica

del automóvil (ECU), y el puerto USB de un ordenador personal.

La parte que engloba el software, que se refiere a la aplicación que

funcionará en el PC y que gestionará el modem interface a partir de los

datos que se vallan recibiendo y enviando atreves del puerto USB.

1.5.1 Descripción básica del hardware (Modem interface)

Para diseñar el modem interface se recurrió a diseños ya existentes y de libre

disposición en la red, con el fin de conseguir construir una interface que

aportase las mejoras que de forma individual cada diseño implementa.

Esta interface contiene como elemento principal un microcontrolador

(PIC18F2550) que es el encargado de gestionar la comunicación entre los dos

periféricos en cuestión, es decir, recoge la información que obtiene del puerto

USB y la interpreta según el protocolo en que se esté comunicando con la ECU.

Esto se debe a que el estándar OBD-II implementa 4 posibles protocolos en su

capa física, SAEJ1850PWM, ISO 9141/14230, J1850 VPW, ISO 15765 (CAN).

Para que el micro pueda realizar estas funciones se dispone además de un

firmware que implementa las capacidades antes descritas, lo que lleva por tanto

a realizar su grabación en el micro, y además a la construcción de un

programador con el cual realizar este proceso.

Otro aspecto importante a resaltar es la necesidad de construir un cable

específico para realizar la conexión entre la ECU y la interface durante las

primeras pruebas, ya que las centralitas electrónicas disponen de un conector

exclusivo para este uso, y por tanto es muy difícil de encontrar en el mercado

material compatible.

Page 13: ProjecteOscar-memoria

13

1.5.2 Descripción básica del software (Interface Visual)

Para realizar la aplicación que gestionará el modem y todos los datos que serán

enviados y recibidos a través de él, se deben realizar primero unos pasos previos

para poder familiarizarse con las rutinas que deberemos utilizar. Como inicio de

este proceso se debe comenzar por averiguar cuál es el mecanismo que siguen

otras aplicaciones que ya implementan este mecanismo, y para poder hacerlo

existe una aplicación, mencionada anteriormente (ScanTool), que ofrece el

código fuente mediante lenguaje C++. A través de este código es posible extraer

las rutinas básicas con las que se realiza la comunicación con el micro y la ECU,

esto permite que nosotros mismos realicemos un programa de prueba con el

que observar cual es la estructura básica que debemos seguir.

Debido a que el objetivo es realizar el software utilizando JAVA, ya que nos

permitirá hacer portable nuestro trabajo a diferentes plataformas, el programa

anterior no es aun suficiente para poder afrontar la implementación de la

aplicación definitiva, y por tanto es necesario realizar otro programa de prueba

que contenga la misma estructura que el anterior pero con código JAVA.

Para poder llevar a cabo este objetivo es necesario utilizar la librería

“RXTXcomm” como librería nativa para realizar las comunicaciones por los

puertos serie, ya que los medios que ofrece la “API” de Java respecto a este tipo

de comunicaciones están obsoletos.

Una vez sabemos utilizar los recursos existentes de Java, se puede empezar a

desarrollar el software que nos ofrecerá las opciones y características que

queremos implementar en la aplicación definitiva.

El objetivo es que el programa pueda permitirnos, a través de una interface

visual, realizar las siguientes tareas:

Opciones para poder configurar los parámetros del puerto serie según convenga.

Opciones para poder seleccionar los protocolos de comunicación que sean necesarios según el vehículo.

Realizar lectura de códigos de error que pueda tener almacenados la centralita electrónica del automóvil.

Realizar lecturas a tiempo real de los datos que aportan los diferentes sensores del motor del vehículo, rpm, velocidad, carga del motor, etc.

Disponer de una consola de texto que monitoree el puerto serie refrescando su contenido según el estado del tráfico de datos entre el PC y el modem interface.

Page 14: ProjecteOscar-memoria

14

2. Diseños

2.1. Metodología utilizada

Durante el desarrollo de este proyecto se ha seguido en parte la filosofía de la

ingeniería inversa para alcanzar algunos de los objetivos, aunque también se

han seguido las pautas de diseños anteriores de disponibilidad libre que realizan

las mismas funciones, ya que encontrar cual es el camino que se sigue para

realizar los procesos adecuadamente en un sector tan cerrado

tecnológicamente como el del automóvil puede llegar a ser muy desesperante.

Este proyecto consta principalmente de un parte de software y otra de

hardware. En lo que hace referencia a la parte física, es decir, el hardware, se ha

utilizado un diseño de libre uso disponible en la red, a partir del cual se

construye básicamente la interface. Este aparato también se comercializa

actualmente con el nombre de ALLProAdapter por la empresa OBDDiag.net y es

una versión compatible de otra interface llamada ELM327, que originalmente es

utilizada por muchos software disponibles de pago, y del cual también se

disponen de los diseños electrónicos, los cuales también se han aprovechado

para realizar el diseño final de la circuitería del modem interface basado en el

PIC18F2550.

El primer paso ha sido comprobar que los programas que existen como

antecedentes funcionen correctamente sobre el hardware montado. De esta

manera se tiene la garantía de que el hardware (interface con PIC18F2550 con

conexión USB), funciona correctamente y de que los programas en los que nos

basaremos para la realización del proyecto son funcionales. De no ser así,

podríamos basarnos en herramientas que no serian útiles.

Una vez verificados estos puntos, el primer objetivo siempre ha sido conseguir

efectuar algún tipo de comunicación con el dispositivo (PIC18F2550) desde el

PC, ya que uno de los problemas comunes a todos los dispositivos de este tipo

es conocer la forma de comunicarse desde el nivel más básico, es decir,

constatar que el micro controlador reacciona o contesta de alguna manera

delante de un estimulo producido mediante una línea de comunicaciones

digital.

Existe un software para el diagnostico de vehículos llamado ScanTool.net, que

en una de sus versiones ofrece el código fuente, muy útil para el propósito de

este proyecto. Este programa ha sido, para este proyecto, la base para poder

iniciar la búsqueda de los pasos que se siguen a la hora de realizar una

comunicación desde el PC hasta la centralita electrónica del vehículo, atreves

del puerto de comunicaciones serie.

Page 15: ProjecteOscar-memoria

15

Además del software de control y el hardware a controlar hay que tener en

cuenta que los microcontroladores necesitan un “driver” para que el sistema

operativo que lo gestiona pueda controlarlo. Dado que el PIC18F2550 lo fabrica

la compañía Microchip, se pensó en que posiblemente esta proporcionara su

“driver”, y aunque así es, lo proporciona mediante la instalación de un paquete

de herramientas llamado “USB Framework package”, el cual obliga a instalar

además del driver muchas otras utilidades que en principio no son necesarias

para este caso. La empresa que ofrece libremente la información para montar la

interface, OBDDiag.net, también proporciona el driver que se necesita, en forma

de fichero INF, y es suficiente para que Windows XP o Vista la detecte sin

problemas. También se pudo averiguar que en otros sistemas operativos,

como por ejemplo Linux, este microcontrolador está contemplado y en las

mismas distribuciones de Linux ya se incorpora el “driver” necesario.

Por tanto, después de montar la interface y verificar su funcionamiento

mediante el software ya existente, se procedió a intentar una comunicación

utilizando recursos propios, es decir, sin recurrir a la funcionalidad de los

programas anteriores. Utilizando el código fuente antes mencionado, el cual se

basa en C++, se diseño un programa de prueba que conseguía comunicarse de

forma básica con el microcontrolador, pero que aportó mucha información para

realizar el proyecto.

Una vez lograda la comunicación se procedió a intentar obtener el mismo

resultado pero utilizando la plataforma Java. Básicamente el programa de

prueba en este caso tiene la misma estructura que en C++, pero utilizando los

recursos de los que dispone Java. El paso más importante aquí fue encontrar

que métodos utiliza Java para comunicarse con el puerto Serie, y aunque los

que proporciona Sun Microsystems, empresa diseñadora de esta plataforma de

programación, están obsoletos, no fue difícil encontrar otros actualizados y

perfectamente compatibles con su máquina virtual. Esta funcionalidad la

proporciona el paquete RXTXcomm junto con la instalación de la maquina

virtual de Java.

Como último objetivo se planteó realizar un software que ofreciese muchas más

funcionalidades de configuración sobre la interface, utilizando un entorno

grafico y mucho mas intuitivo. Este software engloba toda la capacidad de

comunicación de los programas anteriores pero añadiendo todo el potencial

que ofrece un entorno visual diseñado con java, lo cual dota al programa de

muchas opciones de configuración y operatibilidad sobre la interface y por tanto

sobre la centralita electrónica de cualquier vehículo, que, al fin y al cabo, es lo

que se pretende controlar.

Page 16: ProjecteOscar-memoria

16

2.1 Recursos utilizados

Para realizar este proyecto se han utilizado recursos de diferente tipo según si

nos referimos a la parte de software o a la de hardware, pero siempre

recurriendo como fuente principal de información a la que se dispone en la red.

Para montar la interface se recurrió a la web OBDDiag.net, donde se describen

todos los materiales, software, firmware del micro y diseño del PCB necesarios

para construirla. Paralelamente también se sacó información de la web ELM

Electronics, donde mediante los datasheet que ofrecen (ELM327DS.pdf y

ELM320DS.pdf), describen como fabricar un interface para conectarse a la

centralita electrónica (ECU) de cualquier vehículo utilizando los

microcontroladores que ellos suministran. El datasheet ELM327DS, es el

documento que expone todas las posibles ordenes y respuestas que se reciben

y envían al modem interface ELM327 y por tanto también al microcontrolador

que se utiliza en este proyecto, ya que este incorpora un firmware compatible

que contiene la misma estructura básica que el original, el ELM327.

En el siguiente listado se pueden ver todos los posibles comandos que el

ELM327 implementa, y por tanto, aunque no todos los comandos que utiliza la

interface utilizada en este proyecto:

Page 17: ProjecteOscar-memoria

17

Page 18: ProjecteOscar-memoria

18

A continuación podemos ver uno de los esquemas eléctricos que aporta ELM

Electronics, utilizando su microcontrolador más famoso, el antes mencionado

ELM327, el cual utilizan muchas interfaces del mercado, ya que es capaz de

manejar y gestionar los protocolos de comunicación más utilizados en el

estándar OBD-II:

Detalle del esquema eléctrico de un intérprete de OBD a RS232

Page 19: ProjecteOscar-memoria

19

Para realizar el software de control se utilizo como base de inicio el software

que proporciona la empresa ScanTool.net, la cual ofrece en una de sus

versiones su código fuente. Este código fuente se trató con el tan extendido

programa de desarrollo DEV-C++, y posteriormente también se desarrollaron

con él los primeros diseños de prueba con los se empezó la comunicación con la

interface.

Una vez se empezó a programar utilizando la plataforma JAVA y su máquina

virtual, la cual está disponible en la web de Sun Microsystems y se puede

descargar mediante el paquete JDK 6 Update 13, se pasó a utilizar otra

herramienta para programar con este lenguaje llamada Eclipse en su versión

3.2.2, y fue muy útil para desarrollar el entorno gráfico del que dispone el

software de control que se ha creado en este proyecto.

Un recurso muy importante también fue toda la información que se aporta en

RXTX.org, donde se explica el funcionamiento de la librería RXTXcomm.jar, que

es la que se utiliza en JAVA para manejar los puertos serie. En esta web se

ofrecen claros ejemplos de cómo utilizar y configurar los métodos de los que se

dispone, en especial haciendo hincapié en uno de ellos que será adjuntado en el

anexo del proyecto.

Page 20: ProjecteOscar-memoria

20

Por otro lado para poder entender cómo funcionan los protocolos de

comunicación que utiliza el estándar OBDII (On Borad Diagnostics II), se extrajo

mucha información de la enciclopedia libre Wikipedia, donde en uno de sus

documentos (OBD-II PIDs), explica cuales y como son los formatos de trama de

datos que utiliza este estándar, además de documentos como (ASCII), que

detalla las equivalencias del código ascii entre valores decimales y hexadecimal.

Detalle de equivalencias código ASCII

Detalle de la información aportada en el documento OBD PID’s

Page 21: ProjecteOscar-memoria

21

2.3. Descripción del diseño del modem interface

La primera parte del proyecto que se empezó a diseñar y construir es el modem

interface que se utiliza como aparato para interconectar el PC con la centralita

electrónica del vehículo. Este aparato consta de tres partes a diferenciar, el

cable USB que comunica el PC con el modem, el cable OBD-II que comunica la

centralita electrónica del vehículo con el modem y el modem propiamente

dicho. En los cables no hubo ningún proceso de montaje, se podían comprar ya

hechos, pero si se intento fabricar el del conector OBD-II, ya que es difícil

encontrarlos en los comercios especializados, pero se acabó desechando por su

poca durabilidad ya que después de unas pocas pruebas empezó a deteriorarse.

Cable OBD-II a DB9 hembra Cable USB tipo A-B

En la siguiente tabla se puede apreciar la correspondencia entre los pines del

conector OBD-II y el DB9:

OBD-II 16 PIN(Macho) DB9 PIN(Hembra)

(J2850 BUS+) 2 7

(Chassis Ground) 4 1+2

(Signal Ground) 5 1+2

(CAN High J-2284) 6 3

(ISO 9141-2 K Line) 7 4

(J2850 BUS- ) 10 6

(CAN Low J-2284) 14 5

(ISO 9141-2 L Line) 15 8

(Battery Power) 16 9

Page 22: ProjecteOscar-memoria

22

Por tanto el trabajo importante aquí estaba en la fabricación del modem. Para

poder construirlo se acudió a una tienda especializada donde disponían de

todos los componentes electrónicos necesarios, los cuales se procedieron a

instalar en el PCB creado a partir del siguiente “layout” de doble cara:

Page 23: ProjecteOscar-memoria

23

Este aparato contempla la posibilidad de utilizar 4 protocolos de comunicación

distintos a nivel de capa física, ya que a lo largo de los años las diferentes

centralitas electrónicas que montan los fabricantes de vehículos así lo han

dispuesto, aunque a partir del año 2004, en Europa, la mayoría de fabricantes

empezaron a implementar solo el protocolo CAN Bus. Cualquiera de los

vehículos fabricados en EE.UU. a partir del 1996, fueron obligados a disponer de

un puerto OBD2, y en Europa a partir del año 2001, también se obligo a

implantar este tipo de conexión. La norma OBD2 comprende cuatro protocolos

de comunicación distintos:

ISO 9141/14230

J1850 PWM

J1850 VPW

ISO 15765 (CAN)

VPW (Variable Pulse Width) fue originalmente introducido por General Motors,

mientras que PWM (Pulse Width Modulation) pertenece al grupo Ford. ISO 9141

y la posterior encarnación ISO 14230 (AKA Keyword 2000) es el que la mayoría

de vehículos europeos y asiáticos utilizaban. Todos los nuevos modelos a partir

2007/2008 sólo pueden implementar el protocolo CAN Bus. La siguiente imagen

es la de un conector típico OBD2 de 16 pines instalado en cualquier vehículo:

Según el protocolo de comunicación que utilice el vehículo los pines habilitados

en el conector serán diferentes.

El protocolo ISO 9141/14230 utiliza los pines 6 y 15, el protocolo J1850 PWM

utiliza el 2 y el 10, el protocolo J1850 VPW utiliza solo el pin 2, y el protocolo ISO

15765 (CAN), el pin 6 y 14. Todos los protocolos utilizan como fuente de

alimentación los pines 4 y 5 (masa chasis y masa señal respectivamente), y el pin

16 (+12V).

Page 24: ProjecteOscar-memoria

24

Para entender el funcionamiento interno del modem habría que empezar por

describir las partes de las que se compone su circuitería. En la siguiente imagen

se puede observar el esquema eléctrico de la interface:

En el esquema se observa que el microcontrolador utilizado es el PIC18F2455,

pero por dificultades a la hora de adquirirlo se optó por el PIC18F2550, que es

perfectamente compatible además de aportar un poco mas de memoria. Este

micro es el encargado de gestionar todo los componentes periféricos del

circuito y de mantener la comunicación entre ellos, es decir, recibe la

información procedente del puerto USB al que está conectado, la transfiere a

los elementos del circuito que proceda y viceversa, ya que la comunicación es

bidireccional.

La parte del circuito que se ocupa de manejar el protocolo CAN BUS, son los

integrados MCP2515 y MCP2551, el integrado MC33290 maneja el protocolo

ISO9141/14230 junto con Q3, J1850 VPW está controlado por MC33390 y el par

de Mosfets (Q2 P-channel y Q1 N-channel) controlan el bus J1850PWM junto

un comparador interno del PIC18F2550 y las resistencias R4 y R5 que crean la

señal diferencial de la entrada del PWM.

Page 25: ProjecteOscar-memoria

25

2.4 Descripción del diseño del programador JDM2

Después de la explicación anterior es obvio deducir que el elemento más

importante aquí es el microcontrolador PIC18F2550, pero por si solo no tiene

ninguna funcionalidad a no ser que se le introduzca el firmware adecuado, por

esta razón se tuvo que construir exclusivamente para este fin un programador

compatible con el protocolo ICSP (In-Circuit Serial Programming). Este tipo de

programador, llamado JDM2, es muy famoso en la red ya que se construye con

pocos componentes e implementa el estándar ICSP que es el que ofrece la

empresa Microchip para poder introducir los firmwares en los

microcontroladores que ellos fabrican. El esquema eléctrico del programador es

de fácil adquisición en cualquier web de electrónica y se representa con el

siguiente esquema:

Page 26: ProjecteOscar-memoria

26

El circuito se montó en una placa de baquelita específica para realizar

prototipos, y se siguió el siguiente “layout”:

Detalle del programador JDM2 en su parte superior

Detalle del programador JDM2 en su parte inferior (lado soldadura)

Page 27: ProjecteOscar-memoria

27

Además del programador necesitamos poder conectarlo a una PC que disponga

de puerto serie, ya que a través de este puerto se comunicará con el software

que enviará el firmware al micro. La aplicación que se utilizó para programar el

microcontrolador fue “PICPgm Develop. Programer” que es un software gratuito

y de fácil manejo; solo hay que seleccionar el archivo que contenga el firmware

y una vez cargado cliquear en la opción de gravado.

Siguiendo el “datasheet” del microcontrolador se conectó al programador según

el siguiente detalle:

Los pines detallados en la imagen son los que utiliza el programador JDM2 y por

tanto el estándar ICSP, para comunicarse con el PIC. Vemos que además de los

pines de comunicación (MCLR, PGC y PGD), también utiliza el puerto serie para

alimentarse mediante los pines 8 y 19 para masa, y el 20 para los +5 V

necesarios. El pin 26 (PGM), no está implementado en el programador ya que

este solo se utiliza en el caso que se realice una programación en modo “Low-

Voltage ICSP”, y en este caso se realiza en modo “High-Voltage ICSP”.

Page 28: ProjecteOscar-memoria

28

La conexión realizada para proceder a programar el micro fue la siguiente:

En la imagen podemos ver como el cableado procedente del programador está

etiquetado con el nombre de los pines a los cuales debe ser conectado.

Alrededor del micro hay un cable que puentea dos pines, esto se debe a que el

microcontrolador necesita dos puntos de masa. Por otro lado vemos como el

cable procedente del puerto serie está conectado en su el respectivo conector

DB9. También vemos que el programador está dotado de un diodo “led” de

color rojo, el cual es de suma utilidad a la hora de detectar alguna anomalía en

el proceso de gravado.

Page 29: ProjecteOscar-memoria

29

2.5 Modificaciones del diseño del modem

Una vez se había montado la interface y se procedió a comprobar su correcto

funcionamiento con software ya existente, se observó que funcionaba

correctamente en todos los vehículos chequeados los cuales utilizaban

diferentes protocolos de comunicación, exceptuando uno de los casos que no se

obtenía respuesta de su centralita electrónica. Se sospechó que posiblemente la

interface no funcionaba correctamente y se procedió a analizar con un

osciloscopio las señales que producía respecto al protocolo J1850PWM.

Para realizar las mediciones se tuvo recurrir a un osciloscopio digital con una

capacidad de muestro de hasta 1GHz, herramienta que aseguraba el visionado

más que correcto de la señal, ya que además esta era de tipo no periódica y por

tanto con un osciloscopio analógico es prácticamente imposible capturarla.

El resultado fue el siguiente:

Resultado de la trama enviada a través del pin 2 (BUS+) del conector OBD-II

Resultado del trama enviada a través del pin 10 (BUS-) del conector OBD-II

Page 30: ProjecteOscar-memoria

30

Para entender el resultado de estas graficas es preciso hacer una descripción del

comportamiento de la capa física del protocolo j1850PWM. Este protocolo

dispone de dos líneas de comunicación, el BUS+ y BUS-, y se caracteriza por

utilizar la modulación del ancho de pulso (PWM) como mecanismo de

codificación de bits. El periodo de cada bit tiene una duración de 24 µs y su

estado se expresa de la siguiente forma:

Un bit=1, se representa con un estado activo de 8us dentro de un

periodo.

Un bit=0, se representa con un estado activo de 16us dentro de un

periodo.

El BUS+ está activo cuando toma el valor de 5v.

El BUS- está activo cuando toma el valor de 0v.

Por tanto se deduce que en estado de reposo el BUS+ se encuentra a 0 V y el

BUS- a 5 V, a medida que se van enviando los bits los buses van cambiando de

estado quedando siempre entre ellos con tensiones invertidas, lo que se

traduce en un mecanismo de protección contra interferencias exteriores.

Hecha esta explicación podemos darnos cuenta de que la gráfica que representa

el BUS+ desvela un pequeño problema eléctrico, ya que mientras que el BUS-

reacciona rápidamente colocándose a 0 V, el BUS+ nunca llega a lograr los 5 V,

quedándose siempre en los 4,4 V aproximadamente. Aunque este no sería un

problema para realizar la comunicación satisfactoriamente según las

especificaciones del protocolo SAEJ1850PWM, ya que se encuentra dentro de

los márgenes eléctricos permitidos, se procedió a modificar la electrónica que se

ocupa de implementar esta codificación.

Page 31: ProjecteOscar-memoria

31

En el esquema eléctrico observamos que los encargados de ajustar estas

tensiones son los Mosfets Q1 y Q2 (Q2 P-channel y Q1 N-channel) junto con las

resistencias R7 y R6. Partiendo de otro diseño disponible en la red que

implementa el mismo protocolo, se cambiaron los Mosfets por transistores PNP

y NPN (PNP->2N3906 y NPN->2N3904) y las resistencias R6 y R7 de 22kΩ por

resistencias de 2K7 Ω. Además se incorporaron resistencias de protección a las

bases de los transistores de 1KΩ.

Por tanto la modificación resultaría según el siguiente esquema:

Page 32: ProjecteOscar-memoria

32

Debido a que se constató que el problema no venia causado por el hardware se

empezó a investigar si podía venir dado por errores en las tramas enviadas.

Según el estándar J1850 PWM el formato de trama es el siguiente:

A partir de los documentos que explican las características de este protocolo se

averiguo que las diferentes partes de la trama tienen las siguientes funciones:

SOF: Start of frame

Header Field: Son los encargados de especificar mediante 3 bytes los

siguientes parámetros:

El primer byte especifica el modo en que se van a comunicar la

centralita con la interface, y según el documento SAE J2178 este byte

de cabecera se denomina de tipo mapeado, eso significa que cada bit

tiene un significado. Los 8 bit se identifican así:

BIT 7 6 5 4 3 2 1 0

ID P P P H K Y Z Z

Los tres más significativos (7, 6 y 5) indican la prioridad del mensaje y

puede tomar los siguientes valores:

Bit 7 Bit 6 Bit 5

0 0 0 0 Prioridad máxima

0 0 1 1

0 1 0 2

0 1 1 3

1 0 0 4

1 0 1 5

1 1 0 6

1 1 1 7 Prioridad mínima

Page 33: ProjecteOscar-memoria

33

El bit 4 (H) indica si la cabecera es de 3 bytes o uno:

H=0 Tres bytes H=1 Un byte

El bit 3 (K) indica si se utiliza "In-Frame response" ? :

K=0 Requerido K=1 No requerido

El bit 2 (Y) indica si la dirección usada es física o funcional:

Y=0 Funcional Y=1 Física

Los bit 0 y 1 (Z, Z) se usan junto con K e Y para definir el tipo de

mensaje:

Msg. KKYZ Respuesta(K) Dirección(Y) Tipo de mensaje

0 0000 Requerido Funcional “Function”

1 0001 Requerido Funcional “Broadcast”

2 0010 Requerido Funcional “Function Query”

3 0011 Requerido Funcional “Function Read”

4 0100 Requerido Física “Nodo a Nodo”

5 0101 Requerido Física “Reservado-MFG”

6 0110 Requerido Física “Reservado-SAE”

7 0111 No requerido Física “Reservado-MFG”

8 1000 No requerido Funcional “Function Command/Status”

9 1001 No requerido Funcional “Funcion Request/Query”

10 1010 No requerido Funcional “FunctionExt.Command/Status”

11 1011 No requerido Funcional “Function Ext. Request/Query”

12 1100 No requerido Física “Nodo a Nodo”

13 1101 No requerido Física “Reservado-MFG”

14 1110 No requerido Física “No disponible”

15 1111 No requerido Física “Reservado-MFG”

Page 34: ProjecteOscar-memoria

34

El segundo byte representa a la dirección de memoria elegida que

identifica a la centralita (ECU).

El tercer byte representa a la dirección de memoria elegida que

identifica a la interface o herramienta de chequeo.

Data Field: Es la información que se quiere hacer llegar al micro de la

ECU.

CRC: Chequeo de redundancia cíclica de la trama.

Conociendo ya la estructura de este protocolo se pensó que una solución al

problema sería modificar los “Header Field” ya que posiblemente no serian los

adecuados. A partir de aquí se procedió a averiguar cuáles eran los que utilizaba

nuestra interface, y esto se consiguió mediante el comando “ATH1”, el cual le

indica al modem que muestre las cabeceras (Headers) de todas las tramas,

después observando una de las tramas se vio que la cabecera utilizada por

defecto era 6A 61 F1. En el documento antes mencionado (J2178), se indicaba

que esta cabecera es generalmente la más utilizada en muchas de las centralitas

que implementan el protocolo J1850PWM, pero también hacía referencia a otra

posible cabecera a utilizar, que era E4 10 F1.

La cabecera 6A 61 F1 especifica el uso de 0x61 (01100001) como primer byte

que significa prioridad 3, tres bytes de cabecera, tipo de mensaje 2, usando

dirección funcional que es el segundo byte de la cabecera, es decir, 0x6A.

La cabecera E4 10 F1 especifica el uso de 0xE4 (11100100) como primer byte

que indica prioridad 7 (mínima), tres bytes de cabecera, tipo de mensaje 4, con

dirección física y nodo a nodo.

En principio para proceder a cambiar las cabeceras se dispone del comando

“ATSH”, pero por causas aún desconocidas no era reconocido por nuestra

interface, a pesar de que en el firmware del microcontrolador se vio que estaba

implementado, mediante un software para editar ficheros de este tipo.

Utilizando este mismo software (Hex Workshop Hex Editor), se intento

averiguar donde se encontraban los bytes que definían las cabeceras en

cuestión, y después de una búsqueda muy extensa se encontraron y

modificaron con los nuevos valores.

Page 35: ProjecteOscar-memoria

35

En la siguiente captura podemos observar el fragmento de código donde se

encontraban estos datos, fue un tarea laboriosa ya que este fichero solo

contiene tramas hexadecimales, y es el resultado de la compilación de un

código fuente al que no se tenía acceso.

:103C70000350E66EE66A00010028BC6F000E0120CA

:103C8000BD6FBCC0E6FFBDC0E6FF040E0024BE6FE2

:103C9000000E0120BF6FBEC0E6FFBFC0E6FFDDEC37

:103CA0001EF046E90028E96E000E0120EA6E6A0E59

:103CB000EF6E020E0024E96E000E0120EA6E610E26

:103CC000EF6E030E0024E96E000E0120EA6EF10E85

:103CD000EF6E0001030EBC6F00EBE9FF01EBEAFFA2

:103CE000BC51EF2642E9E7CFD9FF1200D9CFE6FF5A

Además de reemplazar estos bytes también se tuvo que recalcular el

“checksum” de cada línea modificada ya que este cambiaba, y el resultado fue

el siguiente:

:103C70000350E66EE66A00010028BC6F000E0120CA

:103C8000BD6FBCC0E6FFBDC0E6FF040E0024BE6FE2

:103C9000000E0120BF6FBEC0E6FFBFC0E6FFDDEC37

:103CA0001EF046E90028E96E000E0120EA6EE40EBA

:103CB000EF6E020E0024E96E000E0120EA6E100E77

:103CC000EF6E030E0024E96E000E0120EA6EF10E85

:103CD000EF6E0001030EBC6F00EBE9FF01EBEAFFA2

:103CE000BC51EF2642E9E7CFD9FF1200D9CFE6FF5A

Con el firmware ya modificado se procedió a volver reescribirlo en el

microcontrolador utilizando el programador antes descrito. Una vez preparada

la interface se volvió a intentar la comunicación con la centralita en cuestión

que nos daba problemas. El resultado fue muy interesante ya que esta vez si nos

contestó pero de la forma no esperada.

La trama enviada fue la siguiente:

E4 10 F1 01 00 0A

Y su respuesta:

C4 F1 10 7F 01 01 00 00 11 41

El dato a resaltar es el 7F 01, que indica respuesta negativa, es decir, según el

documento J2178 una respuesta negativa significa que la centralita electrónica

no dispone de información sobre el modo de trabajo requerido, que es el

“Modo 01”.

Page 36: ProjecteOscar-memoria

36

El estándar OBD-II contempla varios modos de trabajo, entre ellos el modo 01,

modo 03, modo 07, modo 04, modo 09, modo 22 y bastantes más. Cada uno de

ellos se ocupa de una parte de la información que puede aportar la ECU. El

modo más extendido entre todas las centralitas es el modo 01.

Cada modo además especifica sus parámetros PID (Parameter ID), en caso del

modo 01 uno puede ser el parámetro 00, que es el que se utiliza en nuestro

caso. Este parámetro sirve para decirle a la ECU que nos muestre cuales son los

PID que pueden ser utilizados en este modo de entre los PID que se encuentran

numerados del 1 al 20.

Después de consultar nuevamente el documento J2178 se averiguó que cuando

el modo 01 no está disponible en la centralita lo más probable es que se

implementara en su lugar el modo 22. Este fue el final de la investigación ya que

el modo 22 utiliza una longitud de trama más larga que el 01, cosa para la cual

nuestro hardware (el microcontrolador de la interface), no está preparado, ya

que no se implemento en su firmware esta funcionalidad.

Page 37: ProjecteOscar-memoria

37

2.6 Diseño de la aplicación de prueba en C++

Hasta ahora se ha explicado el diseño utilizado para crear la parte de hardware de la

que se compone el proyecto, pero anteriormente se ha hecho referencia también a la

parte de software que es la que tiene más peso y elaboración. El desarrollo del

software se empezó a elaborar a partir del software libre ScanTool.net, que en una de

sus versiones ofrece el código fuente. Utilizando la herramienta Dev-C++ y este

código, el cual se basa en C++, se localizaron los métodos y funciones que se

sospechaban eran los responsables de mantener la comunicación mediante el puerto

serie. El primer paso fue averiguar cuál era la función que realizaba las operaciones

necesarias para realizar las comunicaciones con el PIC. Tras encontrarla y incorporarla

a un programa de prueba, se procedió a compilar la función, tras esto el mismo

compilador mencionaba cuales eran las funciones y variables que llamaba este

método para poder comunicarse, y por lo tanto poder buscarlas en el código anterior

para reunirlas en el programa de prueba. Una vez que se tenían todas las funciones y

variables en el mismo fichero se podía compilar el código sin obtener errores,

averiguando así cómo se comportaba el hilo de ejecución. Después de saber cuál era

la rutina de ejecución, se sacaron todas las órdenes o variables que no son

imprescindibles por realizar una comunicación básica, dejando la clase reducida al

máximo para tener una visión simple del proceso comunicación dejando a la vista

claramente las funciones necesarias. Finalmente el programa de prueba podía

realizar la comunicación enviando órdenes al PIC (atz, 0100, etc...) obteniendo los

mensajes enviados y los recibos con una visualización por consola. A continuación

aparece el código del programa de prueba:

Page 38: ProjecteOscar-memoria

38

Page 39: ProjecteOscar-memoria

39

Este programa utiliza la librería “allegro” como base, un librería muy utilizada

para desarrollar videojuegos, y por tanto era necesario indicarle al compilador

que la cargase con “-lalleg”, aunque también necesita cargar la librería

“iostream” y la “winalleg”, necesaria si se trabaja en Windows. Las funciones

implementadas son:

main(): Arranca el hilo de ejecución.

init(): Carga las librerías y abre el puerto.

deinit(): Descarga las librerías y cierra el puerto.

read_comport(): Lee el puerto serie.

open_comport(): Abre el puerto serie.

Page 40: ProjecteOscar-memoria

40

close_commport(): Cierra el puerto serie.

send_command(): Escribe en el puerto serie.

2.7. Diseño de la aplicación de prueba en JAVA

El segundo diseño se centra en la elaboración de otro programa de prueba a

partir de lenguaje JAVA, ya que era necesario averiguar las capacidades de este

lenguaje a la hora de comunicarse con el puerto serie.

Como primer apunte se ha de decir que se utilizó el IDE para programar en Java

Eclipse. Para poder comunicarse con el puerto serie es necesario incluir las

librerías adecuadas en el paquete de la API de java instalada en el PC, es decir,

en el paquete autoinstalable “JDK-JRE” que ofrece gratuitamente Sun

Microsystems, ya que este no incluye librerías con esta funcionalidad.

Para este fin existe una librería llamada RXTXcomm, disponible en

www.RXTX.org, que mediante métodos nativos dota a Java de la capacidad para

comunicarse con el puerto serie y paralelo, y además puede utilizarse en

cualquier sistema operativo, haciendo hincapié en Windows, ya que aunque Sun

ofrece una API para este fin (Javacomm), no da soporte para este sistema

operativo, quedándose ya esta API obsoleta y aconsejando RXTXcomm.

Descargando y descomprimiendo el “zip” donde se incluyen los ficheros

necesarios de RXTX, debemos de copiar RXTXcomm.jar en la ruta c:\Archivos de

programa\Java\jre\lib\ext, rxtxSerial.dll y rxtxParallel.dll en c:\Archivos de

programa\Java\jre\bin. Si en lugar de Windows nos encontramos en Linux las

rutas donde situar los ficheros es diferente. En Linux debemos de copiar

RXTXcomm.jar en /usr/lib/jvm/jre/lib/ext, los archivos librxtParallel.so y

librxtxSerial.so hay que copiarlos en /usr/lib/jvm/jre/lib/i386 si el sistema es de

32 bits. Con esto el compilador ya tendrá las librerías disponibles y podremos

utilizarla en el código que programemos.

RXTX.org dispone de una web donde se explica el funcionamiento de la librería y

sus métodos, además ofrece ejemplos claros de cómo ponerla en marcha.

Page 41: ProjecteOscar-memoria

41

El programa de prueba que se elaboró en esta fase del proyecto fue el siguiente:

import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.UnsupportedCommOperationException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import java.util.Enumeration; public class Principal CommPortIdentifier idpuerto ; String NombrePuerto ; String ordre ="atz" ; String stringRebut ; SerialPort port ; OutputStream DadesEscriu ; InputStream FluxDades ; Date temps , temps2 ; StringBuffer respuesta ; public Principal() public void conectar() int j=0; for(Enumeration i=CommPortIdentifier. getPortIdentifiers();i.hasMoreElements();) idpuerto = (CommPortIdentifier) i.nextElement(); System. out.print(j++ + ". " + idpuerto .getName()+ "\n" ); //Se examinan todos los puertos disponibles try idpuerto . getPortIdentifier( "COM2"); port = ( SerialPort ) idpuerto .open( "VisualOBD" ,2000); port .setSerialPortParams(9600, SerialPort. DATABITS_8, SerialPort. STOPBITS_1, SerialPort. PARITY_NONE); //Se abre el puerto seleccionado catch (PortInUseException e) e.printStackTrace(); System. out.println( "Puerto en uso." ); catch (NoSuchPortException e) e.printStackTrace(); System. out.println(e); catch (UnsupportedCommOperationException e) e.printStackTrace(); System. out.println(e);

Page 42: ProjecteOscar-memoria

42

public void enviar() temps =new Date(); int data; try DadesEscriu = port .getOutputStream(); for( int i=0;i< ordre .length();i++) data= ordre .codePointAt(i); System. out.println(data); DadesEscriu .write(data );//Se escribe en el Puerto serie if((i+1) == ordre .length()) DadesEscriu .write(13); //Solamente necessita el retorno de carro, //sin el salto de linea. System. out.println( "Enviat atz:" ); catch (IOException e) e.printStackTrace(); System. out.println(e); public void recibir() respuesta =new StringBuffer(); while((timer()- temps .getTime())<3000) char z; int reb=0; try FluxDades = port .getInputStream(); while(reb>-1) reb= FluxDades .read(); //Se lee el Puerto serie z=( char) reb; respuesta .append(z); System. out.println( respuesta ); //Se imprime la respuesta por consola port .close(); catch (IOException e) e.printStackTrace(); System. out.println(e); public static void main(String[] args) Principal prin= new Principal(); prin.conectar(); prin.enviar(); prin.recibir(); public long timer() temps2 = new Date(); return temps2 .getTime();

Page 43: ProjecteOscar-memoria

43

Estructuralmente el programa se asemeja al diseño en C++, y por tanto

implementa métodos funcionalmente muy parecidos:

public static void main(): Método que inicia la ejecución del programa.

public void Conectar(): Establece la conexión con el puerto serie indicado.

public void Enviar(): Escribe la trama de datos a enviar en el puerto serie.

public void recibir(): Lee la trama de datos recibida del puerto serie.

Public long timer(): Método que realiza la espera necesaria a la respuesta

del puerto.

Tanto en JAVA como en C++, el tratamiento de las tramas digitales recibidas y

enviadas en el puerto serie se traducen en valores decimales según el código

ASCII, a partir de su equivalente en binario y posteriormente en hexadecimal.

Unos ejemplos de trama de datos y su tratamiento sería el siguiente:

Comando a enviar: ”atz”-> equivalencia código ASCII:”97,116,122”

Este comando sirve para hacer un “reset” del micro.

Se le añade a la trama el retorno de carro para indicar fin de trama:

“atz\r”->código ASCII:”97,116,122,13” y el método write() de la clase

SerialPort la envía al puerto serie.

Trama recibida del puerto serie atreves del método read() de la clase

SerialPort:

97,116,122,13,10,69,76,77,51,50,55,32,118,49,46,49,32,99,111,109,112,

97,116,105,98,108,101,13,10,62,-1

Equivalencia de la trama según el código ASCII: atz

ELM327 v1.1 compatible

El último número (-1), indica que no se está recibiendo ningún dato, y

sirve como referencia para saber que la trama ha finalizado, además el

micro marca el fin de la trama con el numero 62 ( equivalente a “>”).

Page 44: ProjecteOscar-memoria

44

Comando a enviar: ”01 0C”-> equivalencia código ASCII:” 48,49,48,67”

Este comando sirve para pedirle a la centralita electrónica del vehículo

(ECU), a cuantas revoluciones por minuto (rpm), está girando el motor.

Se le añade a la trama el retorno de carro para indicar fin de trama:

“01 0C\r”->código ASCII:” 48,49,48,67,13” y el método write() de la clase

SerialPort la envía al puerto serie.

Posteriormente cuando la interface la ha recibido esta la envía a la ECU

según el siguiente formato de trama si el protocolo a utilizar es J1850

PWM:

SOF: Start Of Frame

Header Field: 6A 61 F1

Data Field: 01 0C (Comando que se ha especificado antes)

CRC: 0A

EOF: End Of Frame

La ECU contesta con la siguiente trama y la interface la recoge para

enviarla al puerto serie:

6A F1 61 41 0C 0B 88 0A -> Respuesta ECU

01 0C -> Respuesta

6A F1 61 41 0C 0B 88 0A Interface

Se puede observar que la interface le añade a la trama el comando

solicitado

Trama recibida del puerto serie atreves del método read() de la clase

SerialPort:

48,49,48,67,13,10,54,65,70,49,54,49,52,49,48,67,48,66,56,56,48,65,13,1

0,62,-1

Page 45: ProjecteOscar-memoria

45

Por tanto en la respuesta obtenida podemos diferenciar que:

01 0C: Comando requerido

6A F1 61: Cabecera de la trama(Especifica direcciones de memoria,

prioridades, tipo de conexión, etc..)

41 0C: Confirmación de que se ha contestado al comando requerido

sumando 40 a 01, quedando 41 0C.

0B 88: El dato que interesa para calcular las rpm. Según el documento

OBD Pid’s anteriormente mencionado, si pasamos a decimal estos

valores quedando en 11 y 136, y aplicamos esta fórmula

( )( ) ( )738

4

13625611

4

256 =+⋅=+⋅ BA, obtenemos las revoluciones por

minuto del motor a tiempo real.

0A: Chequeo de redundancia cíclica de la trama (CRC).

Page 46: ProjecteOscar-memoria

46

2.5. Diseño de la aplicación grafica diseñada en JAVA

El diseño final y definitivo de este proyecto consistía en realizar un software

multiplataforma diseñado mediante la conocida estructura de programación

“por capas”, para poder unir de forma correcta toda la capacidad de

comunicación que se había conseguido en los programas de prueba anteriores

con la necesidad de ofrecer muchas más opciones, entorno grafico y el potencial

que aporta un entorno visual diseñado con JAVA, lo cual dota al programa de

muchas posibilidades de configuración y operatibilidad sobre la interface y por

tanto sobre la centralita electrónica de cualquier vehículo.

Este software intenta ser compatible con cualquier plataforma que disponga de

una conexión USB o RS-232, de ahí su implementación mediante JAVA, pero

debido a que para realizar las comunicaciones con dichos puertos se ha utilizado

un librería nativa (RXTXcomm.jar), es posible que existan algunas

incompatibilidades de un plataforma a otra, cosa que se debería consultar en la

web de RXTXcomm.

Básicamente el programa ofrece cinco apartados bien diferenciados:

La pantalla principal de inicio: Es la ventana que vemos cuando inicia el

programa, en ella realizamos y vemos las operaciones principales, como

son realizar la conexión/desconexión con la interface y siempre viendo

en una consola de texto los datos que se están enviando y recibiendo a

tiempo real.

La opción de configuración del puerto: En esta sección del programa

podemos configurar todos los parámetros necesarios del puerto serie,

para poder realizar una conexión.

La opción de selección del protocolo de comunicación: Esta funcionalidad

del programa permite que el usuario pueda elegir manualmente el

protocolo con el que se quiere comunicar con la ECU de su vehículo.

La opción de Lectura de códigos de error: Esta opción ofrece la posibilidad

de poder averiguar si nuestro vehículo ha sufrido o sufre algún fallo

técnico, a través de la obtención de un código identificativo que

especifica la avería y que proporciona la ECU.

La opción de mediciones a tiempo real: Esta parte del programa

proporciona información de los diferentes sensores de los que dispone

el motor de nuestro vehículo, mostrando datos como la temperatura,

velocidad, revoluciones por minuto, cantidad de aire absorbido, etc.…

Page 47: ProjecteOscar-memoria

47

Para realizar el software se utilizó la estructura de programación por capas:

capa de datos, capa de dominio y capa de presentación. Cada capa tiene una

función dentro del programa y una serie de clases que cumplen con la función

que se les ha asignado. A continuación se explica la función y clases que

contiene cada capa:

1. Capa de Datos: Es la encargada de gestionar todas las tramas de datos

que se intercambian la computadora y la interface. Su objetivo es

recoger ya sean datos recibidos o enviados, adecuarlos y tratarlos para

poder o bien mandárselos a la interface a través del puerto serie o

recibirlos y mandárselos a las capas superiores. En esta capa podemos

encontrar las siguientes clases:

Clase Conexión: Es la encargada de encapsular todos los atributos de los que se compone una conexión que se realiza atreves del puerto serie: velocidad , dataBits , stopBits , paridad , nombrePuerto , protocolo .

Clase ControladorConexión: Contiene todos los métodos necesarios para realizar la conexión, contiene mucha de la estructura conseguida en los programas de prueba.

Clase lecturaTXTErrores: Clase que permite acceder a archivos de

tipo “TXT”, con el objetivo de que el programa disponga de una memoria permanente. Alguna de las funcionalidades de las que dispone el software necesita cotejar la información que recibe con la que dispone para poder reconocerla, como es el caso de la lectura de los códigos de error.

Clase MuestraIDs: Captura los identificadores de trama del

protocolo CAN Bus.

2. Capa de Dominio: Es la encargada de hacer de intermediario entre la capa de datos y la inmediatamente superior a la de dominio, que en este caso es la de presentación. Ofrece la capacidad de trabajo de la capa de datos, de una forma mucho más accesible para sus capas superiores. En esta capa encontramos la clase ControladorDominioConexión, la cual contiene todos los métodos necesarios para manejar todas las clases que se encuentran en la capa de datos.

Page 48: ProjecteOscar-memoria

48

Capa de Presentación: Esta capa se encarga de gestionar toda la parte visual del programa y contiene todas las clases y controladores necesarios para poder llevar a cabo esta tarea. Concretamente estas son las clases que contiene: ControladorPrincipal y VistaPrincipal: Gestionan la carga de todas las demás clases de la capa de presentación y proporcionan las operaciones básicas del programa, como son poder iniciar o detener un conexión con la interface y seleccionar las diferentes opciones del programa. ControladorErrores y VistaCodigosError: Estas clases se ocupan de gestionar la presentación en pantalla de los códigos de error proporcionados por la ECU. ControladorMediciones y VistaMediciones: Se ocupan de gestionar la presentación en pantalla de los datos referentes a valores que proporcionan los sensores del vehículo, tales como temperatura, velocidad, revoluciones por minuto, cantidad de aire absorbido, etc.… ControladorProtocolo y VistaProtocolo: Gestionan la presentación en pantalla de las opciones disponibles a la hora de seleccionar un protocolo de comunicación. ControladorPSerie y VistaConfiguración: Presentan en pantalla todas las opciones que requiere el puerto serie para ser configurado. Además permiten realizar una búsqueda de estos.

Por lo extenso del código de este último programa, se incorporará al final del proyecto como documento adjunto. En esta aplicación la clase más importante y difícil de desarrollar es la clase ControladorConexion, ya que es la que capacita al software de la capacidad de utilizar varios hilos de ejecución. Esta clase implementa la interface “Runnable” con su respectivo método “Run()”, el cual está en permanente escucha a los mensajes que se envían desde el puerto serie, y por tanto permite liberar al hilo principal para poder realizar otras funciones simultáneamente. Otra de las clases que implementa un nuevo hilo de ejecución es la clase ControladorMediciones, la cual se encarga de mostrar los datos de la lectura a tiempo real de los diferentes sensores de los que dispone la centralita en el vehículo. Por tanto en la aplicación trabajan 3 hilos de ejecución:

Hilo principal: Se mantiene a la espera para realizar las funciones que reclame el usuario.

Hilo de la clase ControladorConexion: Escucha permanentemente el puerto serie consiguiendo así no perder ningún posible dato y una velocidad de respuesta mucho más alta.

Hilo de la clase ControladorMediciones: Refresca constantemente en pantalla los datos que va recibiendo el método run() de la clase ControladorConexión.

Page 49: ProjecteOscar-memoria

49

Cuando se procedió a probar el software sobre diferentes sistemas operativos con la intención de asegurar su funcionalidad, ventaja que tiene JAVA sobre otros lenguajes ya que utiliza una maquina virtual, se observó que en Windows funcionaba correctamente ya que sobre este se había realizado la programación, pero sobre Linux se obtuvo un resultado inesperado. Se observó que en Linux el programa arrancaba y funcionaba de forma correcta, pero en el momento que se procedía a desconectarlo del puerto serie el programa quedaba totalmente bloqueado. Después de muchas pruebas se averiguó que las librerías nativas “RXTXcomm.jar” que utiliza esta aplicación se comportaban de diferente forma según el sistema operativo en el que estuviéramos trabajando. El problema se encontraba en el método run() de la clase ControladorConexión(), ya que este utiliza la clase SerialPort constantemente para escuchar el puerto serie. Observando el siguiente fragmento de código podemos hacernos una idea de la situación: public void run() boolean datos= false; String tramaRecibida; Thread thisThread = Thread. currentThread(); while( hilo == thisThread) char z; int longitudTrama=0; int reb=0; try datosRecibidos = port .getInputStream(); while((reb= datosRecibidos .read() )>-1) z=( char) reb; if(reb==62) break; if(reb!=-1) tramaRecibidaInicial .append(z); DestruirHilo =true; catch (IOException e1) estado( "No response." ); Vemos que la línea subrayada, “datosRecibidos.read()”, es la orden que se encarga de acceder al puerto y cuando el hilo de ejecución llega a ella en Windows la lee una vez y sigue su transcurso dentro del método “run()” hasta el siguiente ciclo de bucle donde lo volvería a leer, pero en Linux no sucede los mismo, el hilo de ejecución se detiene en esta línea esperando un nuevo mensaje del puerto y por tanto bloqueando su posible cierre desde el hilo principal, es decir, como el hilo que se ejecuta en “run()” nunca libera al objeto “port”, cuando accedemos al mismo objeto desde el hilo principal de la clase este provoca un bloqueo de la aplicación ya que nunca tendrá permiso para cerrarlo. Esto se solucionó enviando un mensaje cualquiera al puerto y cambiando en el mismo instante la condición del bucle “while”(hilo=null), para que el hilo de run() saliese de su estado de escucha y acabara extinguiéndose ya que la condición del bucle ya no se cumplía.

Page 50: ProjecteOscar-memoria

50

Como aporte final a esta aplicación se procedió a empaquetarla en un archivo “.jar”, lo que facilita mucho su puesta en marcha y portabilidad a cualquier otra plataforma o sistema operativo. Pero uno de los inconvenientes que presentaba esta aplicación era que para poder comunicarse con los puertos de comunicación necesitaba la librería nativa “RXTXcomm”, y por tanto, esta no viene incluida en las librerías de la maquina virtual que se instala por defecto, lo que obliga a tener que instalarla manualmente. Para cualquier persona que esté familiarizada con la programación no resulta ser un problema, pero si para alguien que solo quiera hacer unas cuantas pruebas. La solución fue crear una carpeta donde se introduciría el archivo “JAR”, los archivos adjuntos necesarios como los “JPG” y “TXT”, y otra carpeta donde incluiríamos la librería nativa “RXTXcomm”. Además de lo anterior se crearon dos archivos ejecutables (RunLinux.sh y RunWindows.bat), que se utilizan según en el sistema operativo en el que estemos. La carpeta se llama VisualOBDJar y contiene los siguientes archivos:

VisualOBD.jar: Archivo comprimido que contiene todo el código de la aplicación.

RunLinux.sh: Archivo ejecutable para Linux.

RunWindows.bat: Archivo ejecutable para Windows.

VisualOBD4_1 y AboutVisualOBD: Archivos de tipo “JPG”.

CodigodErrores.txt: Archivo de texto utilizado como base de datos.

Leeme.txt: Archivo de texto que contiene una breve explicación de cómo arrancar el software.

lib: Carpeta que contiene la librería nativa “RXTXcomm” con los

respectivos archivos “rxtxParallel.dll”, “rxtxSerial.dll”, “librxtxSerial.so”, y “librxtxParallel.so” necesarios para realizar su carga en el sistema operativo través de la máquina virtual.

Page 51: ProjecteOscar-memoria

51

Para poder realizar la carga de la librería nativa correctamente se tuvo que modificar el archivo MANIFEST que contiene el paquete VisualOBD.jar quedando de la siguiente forma:

Y a los archivos RunWindows.bat y RunLinux.sh se les introdujo los siguientes comandos:

Page 52: ProjecteOscar-memoria

52

3. Resultados

3.1. Ámbito de utilización

Este proyecto se basa en un sistema para el chequeo del estado técnico de

cualquiera de los vehículos que actualmente se comercializan o se han

comercializado desde 1996 en EEUU y 2001 en Europa, y por tanto su ámbito de

utilización se puede extender bastante, incluso como pequeña herramienta para

los profesionales del sector o para cualquier persona que disponga de un

vehículo dotado con el sistema On Board Diagnostics-II (OBD-II), que tenga

interés en indagar sobre el estado de su automóvil.

Esta herramienta podría ser muy útil, por ejemplo, para un pequeño taller

mecánico donde su presupuesto para adquirir un aparato de diagnostico es

reducido, y utilizando el sistema descrito aquí podría solucionarle muchos

problemas sin tener que hacer un gran desembolso económico.

Actualmente todos los vehículos de cualquiera de los fabricantes, están

obligados por ley a implementar este estándar, como un mecanismo que facilite

a todo el sector del mantenimiento, el rápido diagnostico de las averías, lo que

garantiza que el sistema que se ha desarrollado será útil en un ámbito muy

extenso.

También hay que decir que es necesario que el usuario tenga un mínimo de

conocimientos sobre la materia para comprender los resultados que muestra el

programa de diagnostico durante el chequeo del vehículo, lo que quizás hace

que se reduzca en parte el ámbito de uso.

Por otro lado en este proyecto se profundiza bastante en el tratamiento de las

comunicaciones realizadas a través del puerto serie utilizando los lenguajes C++

y JAVA, información que puede ser muy útil en todo aquel ámbito que necesite

de esta conexión.

3.2. Validación de los diseños

Una vez terminado el proceso de diseño, el siguiente paso ha sido validar el

proyecto realizando pruebas en diferentes vehículos de diferentes marcas,

teniendo la certeza de que estos estaban equipados con estándar OBD-II. Cada

modelo chequeado disponía de un protocolo de comunicación diferente a nivel

de capa física, con lo que se conseguía comprobar que todos los protocolos que

implementa la interface funcionan.

Page 53: ProjecteOscar-memoria

53

Las pruebas realizadas se realizaron con éxito en los siguientes coches:

Citroen C3 1.4 HDI:

Fabricado en 2004

Equipado con OBD-II y implementa el protocolo ISO 14230-4 KWP2000

Seat Toledo 1.9 TDI:

Fabricado en 2001

Equipado con OBD-II y implementa el protocolo ISO 9141-2

VolksWagen Golf 1.9 TDI:

Fabricado en 2002

Equipado con OBD-II y implementa el protocolo ISO 9141-2

Audi A3 1.9 TDI:

Fabricado en 2001

Equipado con OBD-II y implementa el protocolo ISO 9141-2

Toyota Prius (Motor hibrido)

Fabricado en 2006

Equipado con OBD-II y implementa el protocolo ISO 15765-4 CAN BUS

Seat Leon 1.9 TDI:

Fabricado en 2008

Equipado con OBD-II y implementa el protocolo ISO 15765-4 CAN BUS

Ford Focus TDDi:

Fabricado en 2002

Equipado con OBD-II y implementa el protocolo SAE J1850PWM

Opel Astra 1.6i:

Fabricado en 2001

Equipado con OBD-II y implementa el protocolo SAE J1850VPW

Opel Astra 2.0 DTI:

Fabricado en 2003

Equipado con OBD-II y implementa el protocolo ISO 9141-2

Ford Escort 1.8 TD:

Fabricado en 1998, equipado con OBD-II, implementa el protocolo SAE

J1850PWM, pero no es compatible con nuestro trabajo por incorporar un

modo de trabajo (Modo 22) no contemplado en el proyecto por su poco

uso.

Page 54: ProjecteOscar-memoria

54

3.3. Descripción del funcionamiento

A continuación se describen los pasos a seguir para poner en marcha el sistema

a la hora hacer un chequeo sobre un vehículo. El primer paso es localizar en el

coche el conector OBD-II, ya que cada modelo lo puede incorporar en un lugar

diferente.

Una vez localizado debemos conectar nuestro cable OBD-II el cual proviene de

nuestra interface. Disponiendo de un ordenador portátil o de uno de sobremesa

cercano al lugar donde estemos trabajando, conectamos la interface al puerto

USB. El montaje sería el siguiente si se realiza en un Citroen C3 del año 2004, ya

que con respecto a otro modelo puede variar la localización del conector OBD-II.

Page 55: ProjecteOscar-memoria

55

A partir de aquí podemos arrancar nuestro PC, una vez cargado el sistema

operativo entramos dentro de la carpeta que contiene el software del proyecto

llamada VisualOBDJar. En esta carpeta encontramos dos archivos ejecutables, el

RunLinux.sh y RunWindows.bat, los cuales serán utilizamos según en el sistema

operativo en que estemos trabajando.

En este caso arrancamos RunWindows.bat y nos aparecerá el siguiente entorno

visual:

Page 56: ProjecteOscar-memoria

56

El siguiente paso es realizar la conexión, y para ello debemos arrancar el motor

del coche, seleccionar los parámetros de configuración del puerto serie

(Options->Serial Port Configuration):

Cliqueando en “Search for available ports” obtendremos un lista de los puertos

que tenemos disponibles. Posteriormente en la parte superior seleccionaremos

el puerto en el que esté conectada la interface, y modificaremos los demás

parámetros según sea necesario. Después solo queda cliquear en “Apply” para

confirmar los cambios.

Page 57: ProjecteOscar-memoria

57

Ahora debemos seleccionar el protocolo de comunicación (Options-

>Communication protocol configuration). En el caso de no conocer el protocolo

que se va utilizar, el sistema lo detectará automáticamente:

Vemos que podemos seleccionar el protocolo de comunicación o dejar

seleccionada la opción “Automatic detection of communication protocol”, para

que sea autodetectado. Esta sección también nos proporciona la posibilidad de

modificar las cabeceras de las tramas que se van a enviar. Cada opción (Priority,

ECU Addres, Tool address) se corresponde con un byte dentro de la trama, esto

aumenta las posibilidades de éxito en el momento de conectarse con la ECU, ya

que aunque muchos modelos de centralitas se comunican de la misma forma,

necesitan que se les especifique este parámetro y por tanto modificar el que se

envía por defecto.

Page 58: ProjecteOscar-memoria

58

El siguiente paso es iniciar la conexión cliqueando en “Connect”, si el proceso se ha

realizado con éxito obtendremos la siguiente respuesta:

Observamos que en la consola de texto nos aparecen los comandos

“0100”->”41 00 98 1B 00 11” y “0100”->”86 F1 10 41 00 98 1B 00 11”, lo que

quiere decir que se ha realizado la conexión correctamente y que la ECU

contestó adecuadamente informando de los PID’s (Parameter ID’s) que tiene

disponibles para ser inspeccionados.

Page 59: ProjecteOscar-memoria

59

En caso de que la conexión con la ECU sea fallida este sería el resultado:

Observamos que en la consola de texto se nos comunica que en los comandos

“0100”->”Unable to connect”, no hubo respuesta ya que la captura se trata de

un simple prueba sin conexión a la ECU.

Los demás comandos “AT”, son contestados correctamente porque son datos

procedentes únicamente de la interface, es decir, solo incumben a parámetros

que tienen que ver con el microcontrolador de la interface sin tener en cuenta a

la ECU.

Page 60: ProjecteOscar-memoria

60

Ahora podemos ver un ejemplo de la información que nos daría el programa en

el caso de que el vehículo tuviera almacenados 4 códigos de error indicando así

que se han producido estos fallos técnicos. Para acceder a esta información solo

hay que cliquear en “Read error codes”, estando por supuesto el sistema

correctamente conectado a la ECU:

Este es un ejemplo simulado por eso en la consola de texto seguimos

obteniendo un resultado negativo cuando se envían los comandos

“0100”,”0101” y “03”. El programa nos indica si la luz de chequeo MIL

(Malfunction Indicator Light) situada en el cuadro de mandos, está encendida y

cuantos códigos de error tiene almacenados la ECU. Además se detallan cuales

son los códigos de error y una descripción del significado de estos.

Si además quisiéramos borrar estas fallas almacenadas en la memoria de la

centralita, tendríamos que cliquear en “Clear error codes”, y nos aparecería una

advertencia de seguridad que nos avisaría del paso que vamos a realizar, ya que

si borramos esta información accidentalmente no la podríamos recuperarla.

Page 61: ProjecteOscar-memoria

61

Otra funcionalidad del programa es la lectura de datos a tiempo real de los

sensores que tiene instalados el motor. La cantidad de información que

podemos obtener, depende de la ECU, ya que según el modelo de esta, puede

ofrecer más o menos datos de los sensores que gestiona en la mecánica del

motor. Un ejemplo sería el siguiente:

En la imagen se observan por un lado los datos que se van recibiendo en

formato numérico, es decir, carga del motor, temperatura del refrigerante,

revoluciones por minuto, velocidad actual, temperatura y cantidad de aire

absorbido MAF (Mass Air Flow), y en la consola de texto se observan los mismos

datos pero en formato hexadecimal, que es como la interface los va enviando a

nuestro software. Esta última característica nos permite localizar rápidamente

cualquier incidencia en el proceso de transferencia de datos o en el

procesamiento de la centralita electrónica ya que de no ser así sería mucho más

difícil detectar el problema.

Page 62: ProjecteOscar-memoria

62

En esta captura se observan más datos aportados por la ECU:

Se puede observar que se nos proporciona información sobre la cantidad de

kilómetros que hemos circulado con algún problema técnico indicado con la luz

de chequeo MIL (Malfunction Indicator Lamp) encendida.

Otro dato importante es el de la presión que hay en el circuito de inyección de

combustible en estado de motor a ralentí, proporcionada por la bomba

inyectora a los cilindros. Parece un dato desproporcionado ya que 22070Kpa

equivalen a 220,7 bar de presión, pero teniendo en cuenta que la tecnología hoy

utilizada puede llegar hasta los 2000 bar en el régimen de motor más alto, es

bastante aceptable.

Page 63: ProjecteOscar-memoria

63

En esta otra imagen se observan las mismas lecturas pero realizadas a un

régimen de motor más alto, se ha pasado de estar en 751rpm a 1613.

Observamos que la temperatura de refrigerante es menor que en la captura

anterior, esto se debe a que se tomaron los datos anteriormente. Lo importante

a señalar es que además de ver cambios en la rpm, también los hay en “MAF

Air Flow Rate” ya que el motor necesita absorber más aire. En “Calculated

engine load value” los datos también varían, este dato nos informa sobre la

carga a la que está sometido el motor en ese preciso momento con respecto a la

carga total que podría soportar, y aunque lo lógico sería que aumentase a mas

revoluciones el resultado es todo lo contrario, disminuye. Esto se debe a que

aunque el motor gira a más vueltas, este no debe ejercer ningún esfuerzo ya

que se encuentra parado y por tanto no encuentra ninguna fuerza contraria al

sentido de giro.

Page 64: ProjecteOscar-memoria

64

Una imagen muy determinante para constatar que las lecturas son correctas es

la siguiente:

Observamos que el cuenta revoluciones del panel de instrumentos del vehículo,

está marcando alrededor de las 1500 rpm, dato que se confirma observando la

pantalla del ordenador portátil donde aparece una lectura de 1510 rpm. Se

observa también que hay coincidencia en la velocidad, que es de 0 km/h ya que

nos encontrábamos parados.

Page 65: ProjecteOscar-memoria

65

Hasta ahora el software se ha presentado funcionando bajo sistema operativo

Windows XP, pero también es capaz de funcionar en otros sistemas operativos,

como por ejemplo Linux. En la siguiente imagen podemos apreciarlo:

En la imagen vemos funcionar el software diseñado en este proyecto bajo sistema operativo Linux, concretamente en la distribución Ubuntu en su versión 8.04, con la maquina virtual de JAVA instalada. Respecto a Linux hay que hacer una pequeña aclaración sobre la detección de

los puertos serie. En este sistema operativo los puertos serie se suelen

identificar con nombres como “ttyS0”, “ttyACM0” o “ttyUSB0”, a diferencia de

los COM1, COM2, COM3, etc., de Windows y además se ubican en un carpeta

llamada “/dev”. Por tanto cuando arrancamos el programa en Linux

seleccionamos una de estas opciones y no tendremos ningún problema si

nuestra interface se conecta directamente al puerto RS-232, ya que la detectará

como /dev/ttySO, que es la referencia de dispositivo que siempre es detectada

de forma correcta.

Page 66: ProjecteOscar-memoria

66

Muchas de las interface compatibles utilizan el puerto USB, como es nuestro

caso, y en Windows las detecta también como puerto COM y no encontramos

problemas, pero en Linux estas interface son detectadas como /dev/ttyACM0, y

aquí es donde podemos tener impedimentos, porque este error viene causado

por la librería nativa RXTXcomm, la cual no contempla este tipo de puertos.

Para poder solucionarlo podemos ejecutar la siguiente línea de comando en un

terminal de Linux, con la intención de hacer un linkado simbólico de la interface

“/dev/ttyACM0” con una referencia que si reconozca la librería, por ejemplo

“/dev/ttyS0”:

>ln -sf /dev/ttyS0 /dev/ttyACM0

Después de ejecutar este comando podremos seleccionar el dispositivo “ttyS0”

como si se tratase de “ttyACM0”, y la comunicación se realizará sin ningún tipo

de problema.

3.4. Aplicaciones del proyecto

Como se ha ido viendo durante todo el desarrollo de la memoria, las

aplicaciones de este sistema de diagnosis son bastante obvias. El sistema

diseñado es aplicable al chequeo del estado técnico de cualquiera de los

vehículos que actualmente se comercializan o se han comercializado desde el

año 1996 en EEUU y 2001 en Europa. Es a partir de estas fechas cuando se

obligó a los fabricantes a implantar el estándar OBD-II, y aunque anteriormente

los vehículos también estaban equipados con un sistema de este tipo

precisamente llamado OBD, es decir, el mismo sistema pero en su primera

versión, este no estaba estandarizado entre todos los fabricantes y por tanto

cada uno de ellos implementaba sus propios mecanismos para realizar la auto

diagnosis de sus modelos, lo que lleva a descartar este proyecto en aplicaciones

referentes a este tipo de vehículos.

Por tanto como ejemplo este sistema se puede aplicar en las labores de

manteniendo de cualquier profesional del sector que se encuentre con uno de

los vehículos mencionados anteriormente averiado y que después de su

reparación verifique con esta herramienta si el problema se ha subsanado

correctamente asegurándose de que la ECU no devuelve ningún código de error

o de que el sensor en cuestión ofrece unas lecturas correctas según

especificaciones del fabricante.

Page 67: ProjecteOscar-memoria

67

Otro ejemplo podría ser el que se da normalmente cuando cualquier poseedor

de un vehículo con OBD-II observa que en el cuadro de instrumentos se le ha

encendido una luz llamada “Check Engine” y se pregunta el porqué de este fallo.

En lugar de recurrir al servicio de mantenimiento inmediatamente podemos

proceder a realizar una lectura de “Codigos de Error” obteniendo el posible

código que nos describirá brevemente a que se debe el problema.

Otra de las facetas en las que se puede incluir este sistema es entre aquellas

personas que por puro placer o interés quieren conectarse con su automóvil

para observar los datos que la centralita electrónica les puede ofrecer, con fines

de simple curiosidad.

Como vemos esta herramienta, aunque no está dotada de todo el potencial

posible que ofrece el OBD-II, si aporta una funcionalidad muy útil entre los

posibles usuarios interesados por la mecánica.

4. Comentarios finales

4.1 Plan de trabajo

El plan de trabajo de este proyecto se ha ido desarrollando según los siguientes

puntos:

1. Conseguir todos los componentes y materiales electrónicos necesarios

para construir el modem interface y el programador de PICs.

2. Montar la interface y el programador según el PCB y esquemas eléctricos

especificados en el proyecto.

3. Montar un cable OBD-II para ser utilizado provisionalmente durante las

primeras pruebas.

4. Comprobar el correcto funcionamiento de la interface y familiarizarse

con los comandos “AT” que permiten configurar el microcontrolador

PIC18F2550.

5. Instalar en un ordenador portátil los sistemas operativos WindowsXP y

Linux Ubuntu 8.04 con la respectiva maquina virtual de JAVA.

6. Instalar software compatible con la interface para comprobar su correcto

funcionamiento.

Page 68: ProjecteOscar-memoria

68

7. Conectar la interface a diferentes vehículos para asegurar su

funcionalidad.

8. Programar aplicaciones de prueba en C++ y Java.

9. Programar aplicación utilizando JAVA con un entorno visual lo

suficientemente potente que permita gobernar la interface y la

centralita electrónica de forma estable.

10. Verificar el correcto funcionamiento de la aplicación sobre la interface

mediante pruebas.

11. Verificar el correcto funcionamiento de la aplicación sobre la centralita

electrónica de los vehículos mediante pruebas.

12. Verificar el correcto funcionamiento de la aplicación en diferentes

sistemas operativos, Windows y Linux.

4.2 Listado de materiales

Listado de los materiales para montar el modem interface:

J1 Conector USB tipo B

J2 Conector DB-9 Macho

Q1,Q3 Transistor 2N7000

Q2 Transistor BS250/VP2106

IC1 PIC18F2455

IC2 MC33290

IC3 MC33390/MC33990

IC4 MCP2551/PCA82C250

IC5 MCP2515

X1 Cristal, 16.000Mhz

X2 Cristal, 20.000Mhz

D1 LED verde 5 mm

D2 LED Amarillo 5mm

Page 69: ProjecteOscar-memoria

69

D3 LED rojo 5mm

D4,D5 Diodo 1N4148

R1,R4,R5,R8 10K Ohm

R2,R3 330 Ohm

R6,R7 22K Ohm

R9,R10 510 Ohm

R11,R12 100 Ohm

C1,C2,C4,C5 15pF

C3,C8,C9 0.1uF

C6 0.47uF

C10,C11 560pF

C7 10uF 16V

IC Socket Socket para PIC18F2550 28 pin

Listado de materiales para montar el programador:

J1 Conector DB9 Hembra

D1, D2, D6, D7 Diodo 1N4149

D4 Diodo Zener 6.2 V

D5 Diodo Zener 5.1 V

D3 LED Rojo 5 mm

Q1, Q2 Transistor 2N3904

C1, C4 33pF

C2 100µF 16V

C3 22µF 6.3V

R3 100Ω

R1 1.5KΩ

R2 10KΩ

Page 70: ProjecteOscar-memoria

70

Listado se software y hardware utilizado durante el proyecto:

Bloodshed Dev-C++: Programa utilizado para desarrollo de software en

C++.

Eclipse 3.2: Programa utilizado principalmente para desarrollo de

software en JAVA.

ScanTool: Programa de diagnostico OBD-II basado en microcontrolador

ELM327.

Hex Workshop: Programa para la edición de archivos en formato

hexadecimal.

PICPgm Programer: Utilizado para el gravado del firmware en el

PIC18F2550.

GerbMagic: Programa utilizado para la edición y diseño del circuito

electrónico del modem interface.

JDK 6 Update 13: Paquete instalador de la máquina virtual de JAVA.

PC de sobremesa con WindowsXP Home Edition y Linux Ubuntu 8.04

instalados para realizar la programación.

Ordenador portátil con WindowsXP Home Edition Y Linux Ubuntu 8.04

instalados para realizar las pruebas en los vehículos.

4.3 Presupuesto

La tabla siguiente especifica el presupuesto detallado en euros:

Referencia Cantidad Precio unitario Precio total

Material montaje interface

Material montaje programador

Cable OBD-II a DB9 hembra

Cable USB tipo A-B

Hora trabajo

1

1

1

1

35

20

5

5

2

30

20

5

5

2

1050

Total 1082

Page 71: ProjecteOscar-memoria

71

4.4 Objetivos logrados

Durante todo el proyecto se han ido consiguiendo diferentes objetivos que en

conjunto han hecho que el resultado final haya sido satisfactorio. A

continuación se detallan por puntos:

Conseguir que el montaje de la interface funcione correctamente.

Lograr que el cable OBD-II utilizado previamente para hacer pruebas sea

fiable.

Poder acceder a las centralitas electrónicas (ECU), según el estándar

OBD-II.

Consolidar la comunicación con el modem a través del puerto serie

mediante aplicaciones de software de propio desarrollo en C++ y JAVA.

Conseguir descifrar las tramas digitales para obtener una información

fácilmente comprensible en pantalla de los datos enviados por la ECU.

Finalizar el desarrollo de la aplicación visual en JAVA con todas las

opciones previstas.

Estabilizar la aplicación visual en JAVA sin que se produzca ningún error

ya sea de comunicación con la interface o de manejo respecto al usuario.

Conseguir que la aplicación visual en JAVA funcione correctamente tanto

en Windows como en Linux.

4.5 Conclusiones

El lenguaje de programación JAVA es una herramienta muy potente, ya

que permite que una misma aplicación pueda funcionar de igual forma

en diferentes sistemas operativos y plataformas.

Es posible acceder a la centralita electrónica de un vehículo utilizando

montajes sencillos y ordenadores personales. En realidad está al alcance

de cualquier usuario particular.

Page 72: ProjecteOscar-memoria

72

La ingeniería inversa sobre un “firmware” (desensamblado), tiene

limitaciones y para realizar cambios significativos es necesario disponer

del código fuente, sino estamos limitados a pequeñas modificaciones.

Los fabricantes de automóviles han implementado el estándar OBD-II

obligados por EE.UU. i U.E de una forma bastante compatible como lo

demuestra el que un pequeño dispositivo genérico como el que se ha

realizado, funcione en un amplio rango de vehículos.

El hecho de disponer de un microcontrolador programable disminuye la

dependencia en la plataforma, ya que solo es necesario que disponga de

conexión USB, y a partir de aquí el papel de las plataformas es de

gestionar una conexión serie. El procesado de los protocolos los realiza

el micro.

4.6. Mejoras futuras

Internacionalizar el software de control con la intención de que pueda

mostrar la información en varios idiomas ya que en esta primera versión

solo se muestran en ingles.

Implementar todos los modos de trabajo del estándar OBD-II en el

software de control.

Dotar a la interface de una botonera y un pequeño “display” para poder

realizar las funciones más simples de forma autónoma, como por

ejemplo la lectura y borrado de los códigos de error DTC.

Implementar en el software de control una opción de autoayuda para

poder entender y manejar el sistema de forma más rápida. Esta mejora

sería muy útil porque los datos que se manejan son bastante abstractos.

Crear un paquete instalador que automáticamente sitúe los ficheros

necesarios del software para acelerar su puesta en marcha.

Page 73: ProjecteOscar-memoria

73

Bibliografía

[1] OBD2 ELM327 compatible AllPro adapter with USB, www.obddiag.net

[2] OBD-II PID’s, Wikipedia-The Free Encyclopedia.

[3] ASCII, Wikipedia-The Free Encyclopedia.

[4] OBD-II Trouble Codes Home, OBD-Codes.com

[5] Scanner OBD2, www.gncusers.com.ar

[6] ELM327DS.pdf, www.elmelectronics.com

[7] ELM320DS.pdf, www.elmelectronics.com

[8] 18F2455_2550.pdf, www.microchip.com

[9]Librería nativa “RXTXcomm”, www.rxtx.org

Page 74: ProjecteOscar-memoria

74

Anexo Código ejemplo para el manejo de la librería “RXTXcomm” en lenguaje Java,

disponible en www.rxtx.org:

import gnu.io.CommPort; import gnu.io.CommPortIdentifier; import gnu.io.SerialPort; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class TwoWaySerialComm public TwoWaySerialComm() super(); void connect ( String portName ) throws Excepti on CommPortIdentifier portIdentifier = CommPor tIdentifier.getPortIdentifier(portName);

if ( portIdentifier.isCurrentlyO wned() ) System.out.println("Error: Port is currently in use"); else CommPort commPort = portIde ntifier.open(this.getClass().getName(),2000); if ( commPort instanceof Seria lPort ) SerialPort serialPort = (Se rialPort) commPort; serialPort.setSerialPortPar ams(57600,SerialPort.DATABITS_8, SerialPort.STOPBITS_1,SerialPort.PARITY_NONE); InputStream in = serialPort .getInputStream(); OutputStream out = serialPo rt.getOutputStream(); (new Thread(new SerialReade r(in))).start(); (new Thread(new SerialWrite r(out))).start(); else System.out.println("Error: Only serial ports are handled by this example.");

Page 75: ProjecteOscar-memoria

75

public static class SerialReader implements Ru nnable InputStream in; public SerialReader ( InputStream in ) this.in = in; public void run () byte[] buffer = new byte[1024]; int len = -1; try while ( ( len = this.in.read(buffer )) > -1 ) System.out.print(new String(buf fer,0,len)); catch ( IOException e ) e.printStackTrace(); public static class SerialWriter implements Ru nnable OutputStream out; public SerialWriter ( OutputStream out ) this.out = out; public void run () try int c = 0; while ( ( c = System.in.read()) > - 1 ) this.out.write(c); catch ( IOException e ) e.printStackTrace(); public static void main ( String[] args ) try (new TwoWaySerialComm()).connect("COM3" ); catch ( Exception e ) e.printStackTrace();

Page 76: ProjecteOscar-memoria

76

Código fuente del software de control desarrollado en el proyecto:

Capa de Datos:

Clase Conexión:

package Datos; public class Conexion int velocidad ; int dataBits ; int stopBits ; int paridad ; String nombrePuerto ; String protocolo ; public Conexion( int velocidad, int dataBits, int stopBits, int paridad, String nombrePuerto, String protocol o) super(); this. velocidad = velocidad; this. dataBits = dataBits; this. stopBits = stopBits; this. paridad = paridad; this. nombrePuerto = nombrePuerto; this. protocolo = protocolo; public int getDataBits() return dataBits ; public int getStopBits() return stopBits ; public String getNombrePuerto() return nombrePuerto ; public int getParidad() return paridad ; public int getVelocidad() return velocidad ; public String getProtocolo() return protocolo ;

Page 77: ProjecteOscar-memoria

77

Clase ControladorConexión:

package Datos; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import javax.swing.JTextArea; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.UnsupportedCommOperationException; public class ControladorConexion implements Runnable SerialPort port ; CommPortIdentifier idpuerto ; OutputStream datosEnviados ; InputStream datosRecibidos ; String estado ; StringBuffer tramaEnviada ; StringBuffer tramaRecibidaInicial ; StringBuffer tramaDatos ; StringBuffer tramaDatosCan ; StringBuffer tramaMediciones ; StringBuffer pids_disponibles ; JTextArea respuestaTexto ; String strDatos ; lecturaTXTErrores lecErr ; boolean conexionCOM =false; boolean listo =false; boolean procesaDatos =false; boolean permisoEnvioManual =false; boolean DestruirHilo =false; private volatile Thread hilo ; Date temps , temps2 ; String numeroProtocolo ; Vector<String> ids ; String ID ; MuestraIDs MIDs; Conexion con ; public ControladorConexion(JTextArea respuestaTexto) this. respuestaTexto =respuestaTexto; lecErr = new lecturaTXTErrores(); MIDs = new MuestraIDs(); public void establecerConexion(Conexion con) this. con =con; this. tramaEnviada =new StringBuffer(); this. tramaRecibidaInicial =new StringBuffer(); this. tramaDatos =new StringBuffer(); this. tramaDatosCan =new StringBuffer(); this. tramaMediciones =new StringBuffer(); this. pids_disponibles =new StringBuffer(); this. ID ="" ; this. numeroProtocolo ="0" ;

Page 78: ProjecteOscar-memoria

78

if( conexionCOM ==false) try idpuerto = CommPortIdentifier. getPortIdentifier(con.getNombrePuerto()); catch (NoSuchPortException e) estado( "Port " +con.getNombrePuerto()+ " not available." ); try port = ( SerialPort ) idpuerto .open( "VisualOBD" ,2000); catch (PortInUseException e) estado( "Port " +con.getNombrePuerto()+ " in use." ); try port .setSerialPortParams(con.getVelocidad(), con.getDataBits(), con.getStopBits(), con.getParidad()); catch (UnsupportedCommOperationException e) estado( "Operation not supported." ); hilo =new Thread( this); hilo .start(); hilo .setPriority(Thread. MIN_PRIORITY); conexionCOM =true; estado( "Connected " +con.getNombrePuerto()+ "." ); enviar( "atz" ); enviar(con.getProtocolo()); enviar( "0100" ); enviar( "atdp" ); enviar( "atdpn" ); enviar( "ath1" ); enviar( "0100" ); timer(); public void desconectar() if( conexionCOM ==true) enviar( "atws" ); //En linux el hilo del run, se para en el datosRecibidos.read (), por tanto necessiatmos mandar algo DestruirHilo =false; //para que se mueva de ahi, atws esta bien porque r esetea //la interface al desconectar. while( DestruirHilo ==false) //Espera a que se reciba la ultima trama en run() //para poder despues destruir el hilo y cerrar los //puertos . try Thread. sleep(10); catch (InterruptedException e) e.printStackTrace(); hilo = null; //Obliga a desacer el bucle del hilo para asi parar lo de forma //segura. conexionCOM =false; //Cuando el hilo ya ha recibido la informacion (en linux), //sigue el camino muriendo, ya que hilo=null try datosEnviados .close(); catch (IOException e) estado( "Failed to close communication" ); try

Page 79: ProjecteOscar-memoria

79

datosRecibidos .close(); catch (IOException e) estado( "Failed to close communication." ); try port .disableReceiveFraming(); //Meramente formal port .close(); estado( "Offline." ); catch (Exception e) estado( "Failed to close port" ); else estado( "You are not connected." ); public void enviar(String trama) int longitudTramaEnv=0; int data; listo =false; if( conexionCOM ==true) this. tramaEnviada .append(trama+ "\r" ); //Solamente necessita el retorno de //carro, sin el salto de linea. try datosEnviados = port .getOutputStream(); for( int i=0;i< tramaEnviada .length();i++) data= tramaEnviada .codePointAt(i); datosEnviados .write(data); longitudTramaEnv= tramaEnviada .length(); tramaEnviada .delete(0, longitudTramaEnv); catch (IOException e) estado( "Unable to send " +tramaEnviada +"." ); else estado( "You are not connected to any port." ); public void run() boolean datos= false; String tramaRecibida; Thread thisThread = Thread. currentThread(); while( hilo == thisThread) char z; int longitudTrama=0; int reb=0; try datosRecibidos = port .getInputStream(); while((reb= datosRecibidos .read())>-1) z=( char) reb; if(reb==62) //Cuando se recibe 62 = >, se sale del bucle //para separar los mensajes. //Se hace break en run break; if(reb!=-1) tramaRecibidaInicial .append(z); DestruirHilo =true; //Esto da permiso al metodo desconectar() para //poner el hilo=null.

Page 80: ProjecteOscar-memoria

80

catch (IOException e1) estado( "No response." ); if(reb==62) try tramaRecibidaInicial .deleteCharAt( tramaRecibidaInicial .length()-1); //Se borra el último //salto de linea catch (RuntimeException e2) estado( "No response." ); estado( "Sent " +tramaRecibidaInicial .toString()); tramaRecibida= tramaRecibidaInicial .toString(); longitudTrama= tramaRecibidaInicial .length(); tramaRecibidaInicial .delete(0, longitudTrama); if( permisoEnvioManual ==false) for( int x=0;x<tramaRecibida.length();x++) if(tramaRecibida.codePointAt(x)==10) datos= true; if(datos== true) tramaDatos .append(tramaRecibida.charAt(x)); datos= false; try if(tramaRecibida.codePointAt(0)==97 || tramaRecibida.codePointAt(0)==65) procesaDatos =false; else procesaDatos =true; catch (RuntimeException e2) estado( "No response." ); try if(tramaRecibida.substring(0, 5).toString().compareTo( "atdpn" )==0) if( tramaDatos .codePointAt(1)==65) numeroProtocolo =tramaDatos .substring(2,3); else numeroProtocolo =tramaDatos .substring(1,2); estado( "Protocol number: " +numeroProtocolo ); catch (RuntimeException e1) estado( "No response." ); if( procesaDatos ==true) if(Integer. parseInt( numeroProtocolo )>=6) try if( tramaDatos .codePointAt(8)==52)

Page 81: ProjecteOscar-memoria

81

//El siguiente metodo diferencia l as cabeceras CAN. if( ID .compareTo( "" )==0) ids =new Vector<String>(); for( int f=0;f< tramaDatos .length();f++) if( tramaDatos .codePointAt(f)==10) ids .add( tramaDatos .substring(f+1, f+4)); //Delemito los IDs, //hay que almacenarlos. mostrarIDS( ids ); for( int f=0;f< tramaDatos .length();f++) if( tramaDatos .codePointAt(f)==10) if( ID .compareTo( tramaDatos .substring(f+1, f+4))==0) int longitud=0; try for( int g=f+8; tramaDatos .codePointAt(g)!=10;g++) longitud=g; catch(Exception e) longitud=longitud+1; System. out.println(e); tramaDatosCan .append( "\n" +tramaDatos .substring(f+8,longitud)); //No hacemos break para que asi coja todas las line as con la misma cabecera. strDatos =tramaDatosCan .toString(); longitudTrama= tramaDatosCan .length(); tramaDatosCan .delete(0, longitudTrama); if( ID =="" ) strDatos ="N" ; //Para que los demas metodos sepan que no se han //asignado los ids CAN. else if( tramaDatos .codePointAt(10)==55) strDatos ="Neg" ; //Para que se sepa que hay respuesta negativa. else strDatos ="N" ; //Para que los demas metodos sepan que no a llegado //informacion catch(Exception e) //System.out.println(e); strDatos ="N" ; else try if( tramaDatos .codePointAt(10)==52) for( int f=0;f< tramaDatos .length();f++) if( tramaDatos .codePointAt(f)==10) tramaDatos .delete(f+1, f+10); strDatos =tramaDatos .toString(); else if( tramaDatos .codePointAt(10)==55) strDatos ="Neg" ; //Para que se sepa que hay respuesta negativa. else strDatos ="N" ; //Para que los demas metodos sepan que no a llegado informacion

Page 82: ProjecteOscar-memoria

82

catch(Exception e) //System.out.println(e); strDatos ="N" ; listo =true; longitudTrama= tramaDatos .length(); tramaDatos .delete(0, longitudTrama); permisoEnvioManual =false; public Vector puertosdisponibles() int j=1; Vector <String> listapuertos = new Vector<String>(); for (Enumeration i = CommPortIdentifier. getPortIdentifiers() ; i.hasMoreElements() ;) CommPortIdentifier idpuerto = (CommPortIdentifie r) i.nextElement(); listapuertos.add(j++ + ". " + idpuerto.getName()+ "\n" ); return listapuertos; public void estado(String estado) respuestaTexto .append( ">" +estado+ "\n\n" ); respuestaTexto .setCaretPosition( respuestaTexto .getText().length() ); public String devuelve_cantidad_errores() if( conexionCOM ==true) //esperando cantidad de errores timer(); //strDatos="\n41 01 84 4B A5 F1 0A\r"; //asignando cantidad de errores if( strDatos .compareTo( "N" )==0) return "ECU does not respond." ; else if( strDatos .compareTo( "Neg" )==0) return "ECU responded negatively." ; else if( strDatos .compareTo( "NElm" )==0) return "ELM does not respond." ; else return lecErr .descifraTramaHex( strDatos ); else return "Without connection port." ; public String devuelve_descripcion_errores() //Este metodo coje 2 o mas lineas de errores if( conexionCOM ==true) //Al devolver 2 lineas, entre lineas no hay el //simbolo ">", esto puede ser bueno. //esperando descripcion de errores timer(); //strDatos="\n43 01 33 02 45 61 21 0A\r\n43 01 33 0 2 45 61 21 0A\r"; //asignando cantidad de errores if( strDatos .compareTo( "N" )==0) return "Not received information about errors." ; else if( strDatos .compareTo( "Neg" )==0)

Page 83: ProjecteOscar-memoria

83

return "ECU responded negatively." ; else if( strDatos .compareTo( "NElm" )==0) return "ELM does not respond." ; else return lecErr .descifraTramaHexDescripcionErrores( strDatos +"\n" ); else return "First you must connect to the COM port." ; public String borrado_de_errores() if( conexionCOM ==true) timer(); //strDatos="\n44 0A\r"; if( strDatos .compareTo( "N" )==0) return "ECU does not respond." ; else if( strDatos .compareTo( "Neg" )==0) return "ECU responded negatively." ; else if( strDatos .compareTo( "NElm" )==0) return "ELM does not respond." ; else return "Removed errors stored in the ECU.." ; else return "Without connection port." ; public String devuelve_pid() timer(); //strDatos="\n41 0C 04 88 8F B0\r"; if( strDatos .compareTo( "N" )==0) strDatos ="\n41 0C 00 00 00 00\r" ; //Para que no pete el hilo de mediciones si llega //un NO DATA o algo inadecuado. estado( "ECU does not respond" ); return strDatos ; else if( strDatos .compareTo( "Neg" )==0) strDatos ="\n41 0C 00 00 00 00\r" ; estado( "ECU responded negatively" ); return strDatos ; else if( strDatos .compareTo( "NElm" )==0) strDatos ="\n41 0C 00 00 00 00\r" ; estado( "ELM does not respond" ); return strDatos ; else return strDatos ; public boolean estado_conexion() return conexionCOM ; public void borrar_pids_establecidos() int longitudTrama; longitudTrama= pids_disponibles .length(); pids_disponibles .delete(0, longitudTrama); public void establece_pids() if( conexionCOM ==true) //esperando pids

Page 84: ProjecteOscar-memoria

84

timer(); //asignando pids String pids_binario; //strDatos="\n41 00 FF FF FF FF 0A\r"; int pids_decimal; int longitud_trama; int t=7; if( strDatos .compareTo( "N" )==0) pids_disponibles .append( "N00000000000000000000000000000000" ); estado( "ECU does not respond" ); else if( strDatos .compareTo( "Neg" )==0) pids_disponibles .append( "N00000000000000000000000000000000" ); estado( "ECU responded negatively" ); else if( strDatos .compareTo( "NElm" )==0) pids_disponibles .append( "N00000000000000000000000000000000" ); estado( "ELM does not respond" ); else for( int q=0;q<4;q++) //Da 4 pasadas para lo 4 bytes de datos for( int r=t;r<(t+2);r++) //coje los bytes, en grupos de 2 chars tramaMediciones .append( strDatos .charAt(r)); t=t+3; pids_decimal=Integer. parseInt( tramaMediciones .toString(), 16); //pasa de hex a int pids_binario=Integer. toString(pids_decimal, 2); //pasa de int a bin longitud_trama= tramaMediciones .length(); tramaMediciones .delete(0, longitud_trama); for( int f=0;f<(8-pids_binario.length());f++) //introduce un 0 al //p rincipio de las tramas de menos de 8 bits pids_disponibles .append( "0" ); pids_disponibles .append(pids_binario); public String cojer_pids() if( conexionCOM ==true) if( pids_disponibles .codePointAt(0)!=78) //Si los datos que llegan empiezan por N return pids_disponibles .toString(); else estado( "No data available pids" ); return "N" ; else estado( "Without connection port." ); return "N" ; public void mostrarIDS(Vector vect) MIDs.getJListIDs().setListData(vect); MIDs.getJListIDs().setSelectedIndex(0); MIDs.setVisible( true); MIDs.getJButtonIDsAceptar().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) asignaIDCanBus(); MIDs.setVisible( false); );

Page 85: ProjecteOscar-memoria

85

public void asignaIDCanBus() ID =MIDs.getJListIDs().getSelectedValue().toString(); public void timer() temps =new Date(); while(agafatemps()- temps .getTime()<5000) //Espera 5 segundos la respuesta del puerto procedente de la interface ELM. try Thread. sleep(10); catch (InterruptedException e) e.printStackTrace(); if( listo ==true) break; if( listo ==false) estado( "Without connection to the interface ELM." ); strDatos ="NElm" ; listo =true; public void permiteEnvioManual( boolean permiso) permisoEnvioManual =permiso; //Avilita el envio manual de ordenes a la interface ELM. public long agafatemps() //Metodo que utiliza el timer(). temps2 = new Date(); return temps2 .getTime();

Clase lecturaTXTErrores:

package Datos; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class lecturaTXTErrores FileReader fr ; BufferedReader bf ; int longitudTrama ; int numeroErrores ; StringBuffer valorHex ; public lecturaTXTErrores()

Page 86: ProjecteOscar-memoria

86

public String descifraTramaHex(String error) String estadoErrores; int valorDec; valorDec=Integer. parseInt(error.substring(7, 9), 16); if(valorDec<128) estadoErrores= "The check engine light (MIL) is OFF, and the ECU d oesn't have any error code stored" ; else numeroErrores =valorDec-128; estadoErrores= "The check engine light (MIL) is ON, and the ECU ha s " +numeroErrores +" error code/s stored" ; return estadoErrores; public String descifraTramaHexDescripcionErrores(String e rror) valorHex = new StringBuffer(); StringBuffer codigoError= new StringBuffer(); int incremento=4; for( int s=0;s< numeroErrores ;s++) boolean codigo_encontrado= false; if(error.codePointAt(incremento)==48) valorHex .append( "P0" ); else if(error.codePointAt(incremento)==49) valorHex .append( "P1" ); else if(error.codePointAt(incremento)==50) valorHex .append( "P2" ); else if(error.codePointAt(incremento)==51) valorHex .append( "P3" ); else if(error.codePointAt(incremento)==52) valorHex .append( "C0" ); else if(error.codePointAt(incremento)==53) valorHex .append( "C1" ); else if(error.codePointAt(incremento)==54) valorHex .append( "C2" ); else if(error.codePointAt(incremento)==55) valorHex .append( "C3" ); else if(error.codePointAt(incremento)==56) valorHex .append( "B0" ); else if(error.codePointAt(incremento)==57) valorHex .append( "B1" ); else if(error.codePointAt(incremento)==65) valorHex .append( "B2" ); else if(error.codePointAt(incremento)==66) valorHex .append( "B3" ); else if(error.codePointAt(incremento)==67) valorHex .append( "U0" ); else if(error.codePointAt(incremento)==68) valorHex .append( "U1" ); else if(error.codePointAt(incremento)==69) valorHex .append( "U2" ); else if(error.codePointAt(incremento)==70) valorHex .append( "U3" ); for( int p=incremento+1;p<(incremento+5);p++) //Introduce el resto de //numeros del error if(error.codePointAt(p)!=32) valorHex .append(error.charAt(p));

Page 87: ProjecteOscar-memoria

87

incremento=incremento+6; //Coloca la posicion en la trama para el siguiente //error if(error.codePointAt(incremento+3)==10) //Si detecta salto de linea se //prepara la posicion para el siguiente error en la siguiente linea incremento=incremento+7; String codError= valorHex .toString(); String sCadena; try fr = new FileReader( "CodigosErrores.txt" ); bf = new BufferedReader( fr ); while ((sCadena = bf .readLine())!= null) if(codError.compareTo(sCadena.substring(0, 5))==0) //se compara //el error leido con cada linea del fichero, si lo encuentra se sale del bucle codigoError.append(sCadena+ "\n\n" ); codigo_encontrado= true; break; if(codigo_encontrado== false) codigoError.append( "Unknown " +codError+ " error\n\n" ); catch (IOException e) codigoError.append( "Database error codes inaccessible" ); longitudTrama =valorHex .length(); //Se deja vacio el buffer que contiene el //código procedente de la ECU valorHex .delete(0, longitudTrama ); return codigoError.toString();

Page 88: ProjecteOscar-memoria

88

Clase MuestraIDs:

package Datos; import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.JList; import java.awt.Rectangle; import javax.swing.JButton; import javax.swing.JScrollPane; public class MuestraIDs extends JFrame private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JList jListIDs = null; private JButton jButtonIDsAceptar = null; private JScrollPane jScrollPaneListaIDs = null; public MuestraIDs() super(); initialize(); private void initialize() this.setSize(300, 200); this.setLocation(500, 200); this.setContentPane(getJContentPane()); this.setTitle( "CAN Bus IDs" ); private JPanel getJContentPane() if ( jContentPane == null) jContentPane = new JPanel(); jContentPane .setLayout( null); jContentPane .add(getJButtonIDsAceptar(), null); jContentPane .add(getJScrollPaneListaIDs(), null); return jContentPane ; public JList getJListIDs() if ( jListIDs == null) jListIDs = new JList(); return jListIDs ; public JButton getJButtonIDsAceptar() if ( jButtonIDsAceptar == null) jButtonIDsAceptar = new JButton(); jButtonIDsAceptar .setBounds( new Rectangle(200, 133, 82, 22)); jButtonIDsAceptar .setText( "OK" ); return jButtonIDsAceptar ;

Page 89: ProjecteOscar-memoria

89

private JScrollPane getJScrollPaneListaIDs() if ( jScrollPaneListaIDs == null) jScrollPaneListaIDs = new JScrollPane(); jScrollPaneListaIDs .setBounds( new Rectangle(10, 10, 273, 115)); jScrollPaneListaIDs .setViewportView(getJListIDs()); return jScrollPaneListaIDs ;

Capa de Dominio:

Clase ControladorDominioConexión:

package Dominio; import java.util.Vector; import javax.swing.JTextArea; import Datos.Conexion; import Datos.ControladorConexion; public class ControladorDominioConexion Conexion con ; ControladorConexion contCon ; public ControladorDominioConexion(JTextArea respuestaText o) contCon = new ControladorConexion(respuestaTexto); public void establecerConexion( int velocidad, int dataBits, int stopBits, int paridad,String n ombrePuerto,String protocolo) con = new Conexion(velocidad,dataBits,stopBits,paridad,nombr ePuerto,protocolo); contCon .establecerConexion( con ); public void enviar(String tramaEnviada) contCon .enviar(tramaEnviada); public void desconectar() contCon .desconectar(); public Vector puertosdisponibles() return contCon .puertosdisponibles(); public String devuelve_cantidad_errores() return contCon .devuelve_cantidad_errores(); public String devuelve_descripcion_errores() return contCon .devuelve_descripcion_errores(); public boolean estado_conexion() return contCon .estado_conexion();

Page 90: ProjecteOscar-memoria

90

public String cojer_pids() return contCon .cojer_pids(); public String devuelvePid() return contCon .devuelve_pid(); public void establece_pids() contCon .establece_pids(); public String borrado_de_errores() return contCon .borrado_de_errores(); public void borrar_pids_establecidos() contCon .borrar_pids_establecidos(); public void permiteEnvioManual( boolean permiso) contCon .permiteEnvioManual(permiso);

Capa de Presentación:

Clase ConfirmaciónBorradoErrores:

package Presentacion; import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.JLabel; import java.awt.Rectangle; import javax.swing.JButton; public class ConfirmacionBorradoErrores extends JFrame private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JLabel jLabelConfirmaErrores = null; private JButton jButtonOK = null; private JLabel jLabelConfirmarBorradoErrores = null; private JButton jButtonCancel = null;

public ConfirmacionBorradoErrores() super(); initialize(); private void initialize() this.setSize(330, 200); this.setLocation(500,200); this.setContentPane(getJContentPane());

Page 91: ProjecteOscar-memoria

91

this.setTitle( "Confirm erasing error codes" ); private JPanel getJContentPane() if ( jContentPane == null) jLabelConfirmarBorradoErrores = new JLabel(); jLabelConfirmarBorradoErrores .setBounds( new Rectangle(10, 41, 206, 20)); jLabelConfirmarBorradoErrores .setText( "Do you really want to continue?" ); jLabelConfirmaErrores = new JLabel(); jLabelConfirmaErrores .setBounds( new Rectangle(10, 20, 308, 20)); jLabelConfirmaErrores .setText( "You will erase all error codes stored in the ECU." ); jContentPane = new JPanel(); jContentPane .setLayout( null); jContentPane .add( jLabelConfirmaErrores , null); jContentPane .add(getJButtonOK(), null); jContentPane .add( jLabelConfirmarBorradoErrores , null); jContentPane .add(getJButtonCancel(), null); return jContentPane ; public JButton getJButtonOK() if ( jButtonOK == null) jButtonOK = new JButton(); jButtonOK .setBounds( new Rectangle(161, 135, 75, 20)); jButtonOK .setText( "OK" ); return jButtonOK ; public JButton getJButtonCancel() if ( jButtonCancel == null) jButtonCancel = new JButton(); jButtonCancel .setBounds( new Rectangle(235, 135, 75, 20)); jButtonCancel .setText( "Cancel" ); return jButtonCancel ;

Page 92: ProjecteOscar-memoria

92

Clase ControladorErrores:

package Presentacion; import javax.swing.JPanel; import Dominio.ControladorDominioConexion; public class ControladorErrores VistaCodigosError VCE; ControladorDominioConexion contDom ; ControladorMediciones contMed ; ConfirmacionBorradoErrores confErr ; boolean ventanaConfirmaErrores ; public ControladorErrores(ControladorDominioConexion cont Dom,ControladorMediciones contMed) this. contMed =contMed; VCE = new VistaCodigosError(); this. contDom = contDom; ventanaConfirmaErrores =false; eventos(); public void eventos() VCE.getJButtonErrores().addMouseListener( new java.awt.event.MouseAdapter() public void mouseClicked(java.awt.event.MouseEvent e) if( contMed . lectura ==true) contMed . pararHilo =true; contMed . inicializacion =true; contMed . lectura =false; while( contMed . indica_hilo_destruido ==false) try Thread. sleep(10); catch (InterruptedException error) error.printStackTrace(); consulta_errores(); ); VCE.getJButtonBorrarErrores().addMouseListener( new java.awt.event.MouseAdapter() public void mouseClicked(java.awt.event.MouseEvent e) if( ventanaConfirmaErrores ==false) confirmaErrores(); ventanaConfirmaErrores =true; //Esta variable evita que podamos //abrir varias ventanas. ); public void consulta_errores() contDom .enviar( "0101" ); VCE.getJTextAreaErrores().append( contDom .devuelve_cantidad_errores()+ "\n\n" ); contDom .enviar( "03" ); VCE.getJTextAreaErrores().append( contDom .devuelve_descripcion_errores()+ "\n\n" ); public JPanel devuelve_panel() return this. VCE;

Page 93: ProjecteOscar-memoria

93

public void confirmaErrores() confErr =new ConfirmacionBorradoErrores(); confErr .setVisible( true); confErr .getJButtonOK().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) contDom .enviar( "04" ); VCE.getJTextAreaErrores().append( contDom .borrado_de_errores()+ "\n\n" ); confErr .setVisible( false); ventanaConfirmaErrores =false; ); confErr .getJButtonCancel().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) confErr .setVisible( false); ventanaConfirmaErrores =false; ); confErr .addWindowListener( new java.awt.event.WindowAdapter() public void windowClosing(java.awt.event.WindowEvent e) confErr .setVisible( false); ventanaConfirmaErrores =false; );

Clase ControladorMediciones:

package Presentacion; import java.text.DecimalFormat; import javax.swing.JPanel; import Dominio.ControladorDominioConexion; public class ControladorMediciones implements Runnable VistaMediciones VMed; ControladorDominioConexion contDom ; String pids_disponibles ; DecimalFormat df ; boolean lectura =false; boolean pararHilo =false; boolean inicializacion =false; boolean indica_hilo_destruido ; boolean conectado =false; Thread hilo ; public ControladorMediciones(ControladorDominioConexion c ontDom) VMed = new VistaMediciones(); this. contDom = contDom; df = new DecimalFormat( "0.0" ); //Especifica los decimales mostrados en las TextFie ld. eventos();

Page 94: ProjecteOscar-memoria

94

public void eventos() VMed.getJButtonLeer().addMouseListener( new java.awt.event.MouseAdapter() public void mouseClicked(java.awt.event.MouseEvent e) if( lectura ==false) if( conectado ==true) if( inicializacion ==true) hilo = new Thread(ControladorMediciones. this); inicializacion =false; indica_hilo_destruido =false; contDom .borrar_pids_establecidos(); contDom .enviar( "0100" ); contDom .establece_pids(); contDom .enviar( "0120" ); contDom .establece_pids(); contDom .enviar( "0140" ); contDom .establece_pids(); pids_disponibles =contDom .cojer_pids(); if( pids_disponibles .codePointAt(0)==78) lectura =false; else pararHilo =false; lectura =true; hilo .start(); else contDom .enviar( "0100" ); ); VMed.getJButtonDetener().addMouseListener( new java.awt.event.MouseAdapter() public void mouseClicked(java.awt.event.MouseEvent e) if( conectado ==true) pararHilo =true; lectura =false; inicializacion =true; else contDom .enviar( "0100" ); ); public JPanel devuelve_panel() return this. VMed; public void run() while( true) if( pids_disponibles .codePointAt(3)==49) contDom .enviar( "0104" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField04().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(4)==49) contDom .enviar( "0105" );

Page 95: ProjecteOscar-memoria

95

int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField05().setText(Integer. toString(valorDec-40)+ "ºC" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(5)==49) contDom .enviar( "0106" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField06().setText( df .format(((valorDec-128)*100)/128)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(6)==49) contDom .enviar( "0107" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField07().setText( df .format(((valorDec-128)*100)/128)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(7)==49) contDom .enviar( "0108" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField08().setText( df .format(((valorDec-128)*100)/128)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(8)==49) contDom .enviar( "0109" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField09().setText( df .format(((valorDec-128)*100)/128)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(9)==49) contDom .enviar( "010A" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField0A().setText(Integer. toString(valorDec*3)+ "kPa" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(10)==49) contDom .enviar( "010B" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField0B().setText(Integer. toString(valorDec)+ "kPa" ); if( pararHilo ==true) indica_hilo_destruido =true; break;

Page 96: ProjecteOscar-memoria

96

if( pids_disponibles .codePointAt(11)==49) contDom .enviar( "010C" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField0C().setText(Integer. toString(((a*256)+b)/4)+ "rpm" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(12)==49) contDom .enviar( "010D" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField0D().setText(Integer. toString(valorDec)+ "km/h" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(13)==49) contDom .enviar( "010E" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField0E().setText( df .format((valorDec/2)-64)+ "º" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(14)==49) contDom .enviar( "010F" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField0F().setText(Integer. toString(valorDec-40)+ "ºC" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(15)==49) contDom .enviar( "0110" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField10().setText( df .format(((a*256)+b)/100)+ "g/s" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(16)==49) contDom .enviar( "0111" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField11().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(17)==49) contDom .enviar( "0112" ); StringBuffer trama_binaria= new StringBuffer(); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); String pids_binario=Integer. toString(valorDec, 2);

Page 97: ProjecteOscar-memoria

97

for( int f=0;f<(8-pids_binario.length());f++) //introduce un 0 al principio //de las tramas de menos de 8 bits trama_binaria.append( "0" ); trama_binaria.append(pids_binario); if(trama_binaria.codePointAt(7)==49) VMed.getJTextField12().setText( "Upstream of catalytic converter" ); else if(trama_binaria.codePointAt(6)==49) VMed.getJTextField12().setText( "Downstream of catalytic converter" ); else if(trama_binaria.codePointAt(5)==49) VMed.getJTextField12().setText( "From the outside atmosphere or off" ); else VMed.getJTextField12().setText( "OK" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(19)==49) contDom .enviar( "0114" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField14().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(20)==49) contDom .enviar( "0115" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField15().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(21)==49) contDom .enviar( "0116" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField16().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(22)==49) contDom .enviar( "0117" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField17().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break;

Page 98: ProjecteOscar-memoria

98

if( pids_disponibles .codePointAt(23)==49) contDom .enviar( "0118" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField18().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(24)==49) contDom .enviar( "0119" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField19().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(25)==49) contDom .enviar( "011A" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField1A().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(26)==49) contDom .enviar( "011B" ); int voltios=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int porcentaje=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField1B().setText( df .format(voltios*(0.005))+ "V " +df .format((porcentaje-128)*(100/128))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(27)==49) contDom .enviar( "011C" ); String valorHex= contDom .devuelvePid().substring(7,9); if(valorHex.compareTo( "01" )==0) VMed.getJTextField1C().setText( "OBD-II as defined by the CARB" ); else if(valorHex.compareTo( "02" )==0) VMed.getJTextField1C().setText( "OBD as defined by the EPA" ); else if(valorHex.compareTo( "03" )==0) VMed.getJTextField1C().setText( "OBD ''and'' OBD-II" ); else if(valorHex.compareTo( "04" )==0) VMed.getJTextField1C().setText( "OBD-I" ); else if(valorHex.compareTo( "05" )==0) VMed.getJTextField1C().setText( "Not meant to comply with any OBD standard" ); else if(valorHex.compareTo( "06" )==0) VMed.getJTextField1C().setText( "EOBD");

Page 99: ProjecteOscar-memoria

99

else VMed.getJTextField1C().setText( "Unknown" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(29)==49) contDom .enviar( "011E" ); StringBuffer trama_binaria= new StringBuffer(); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); String pids_binario=Integer. toString(valorDec, 2); for( int f=0;f<(8-pids_binario.length());f++) //introduce un 0 al principio //de las tramas de menos de 8 bits trama_binaria.append( "0" ); trama_binaria.append(pids_binario); if(trama_binaria.codePointAt(7)==49) VMed.getJTextField1E().setText( "Active" ); else VMed.getJTextField1E().setText( "No active" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(30)==49) contDom .enviar( "011F" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField1F().setText( df .format((a*256)+b)+ "segs" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(31)==49) if( pids_disponibles .codePointAt(32)==49) contDom .enviar( "0121" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField21().setText(Integer. toString((a*256)+b)+ "km" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(33)==49) contDom .enviar( "0122" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField22().setText( df .format(((a*256)+b)*(0.079))+ "kPa" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(34)==49) contDom .enviar( "0123" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16);

Page 100: ProjecteOscar-memoria

100

int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField23().setText(Integer. toString(((a*256)+b)*10)+ "kPa" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(35)==49) contDom .enviar( "0124" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField24().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(36)==49) contDom .enviar( "0125" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField25().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(37)==49) contDom .enviar( "0126" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField26().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(38)==49) contDom .enviar( "0127" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField27().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(29)==49) contDom .enviar( "0128" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField28().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(40)==49) contDom .enviar( "0129" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField29().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true)

Page 101: ProjecteOscar-memoria

101

indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(41)==49) contDom .enviar( "012A" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField2A().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(42)==49) contDom .enviar( "012B" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField2B().setText( df .format(((c*256)+d)*(0.000122))+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(43)==49) contDom .enviar( "012C" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField2C().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(44)==49) contDom .enviar( "012D" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField2D().setText( df .format((valorDec*(0.78125))-100)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(45)==49) contDom .enviar( "012E" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField2E().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(46)==49) contDom .enviar( "012F" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField2F().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break;

Page 102: ProjecteOscar-memoria

102

if( pids_disponibles .codePointAt(48)==49) contDom .enviar( "0131" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField31().setText(Integer. toString((a*256)+b)+ "km" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(49)==49) contDom .enviar( "0132" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField32().setText( df .format((((a*256)+b)/4)-(8.192))+ "Pa" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(50)==49) contDom .enviar( "0133" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField33().setText(Integer. toString(valorDec)+ "kPa" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(51)==49) contDom .enviar( "0134" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField34().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(52)==49) contDom .enviar( "0135" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField35().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(53)==49) contDom .enviar( "0136" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField36().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(54)==49) contDom .enviar( "0137" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16);

Page 103: ProjecteOscar-memoria

103

int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField37().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(55)==49) contDom .enviar( "0138" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField38().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(56)==49) contDom .enviar( "0139" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField39().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(57)==49) contDom .enviar( "013A" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField3A().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(58)==49) contDom .enviar( "013B" ); int c=Integer. parseInt( contDom .devuelvePid().substring(13,15), 16); int d=Integer. parseInt( contDom .devuelvePid().substring(16,18), 16); VMed.getJTextField3B().setText( df .format(((c*256)+d)*(0.00390625)-128)+ "mA" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(59)==49) contDom .enviar( "013C" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField3C().setText( df .format((((a*256)+b)/10)-40)+ "ºC" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(60)==49) contDom .enviar( "013D" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField3D().setText( df .format((((a*256)+b)/10)-40)+ "ºC" ); if( pararHilo ==true)

Page 104: ProjecteOscar-memoria

104

indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(61)==49) contDom .enviar( "013E" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField3E().setText( df .format((((a*256)+b)/10)-40)+ "ºC" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(62)==49) contDom .enviar( "013F" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField3F().setText( df .format((((a*256)+b)/10)-40)+ "ºC" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(63)==49) if( pids_disponibles .codePointAt(65)==49) contDom .enviar( "0142" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField42().setText( df .format(((a*256)+b)/1000)+ "V" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(66)==49) contDom .enviar( "0143" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField43().setText( df .format(((a*256)+b)*(100/255))+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(67)==49) contDom .enviar( "0144" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField44().setText( df .format(((a*256)+b)*(0.0000305))); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(68)==49) contDom .enviar( "0145" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField45().setText( df .format((valorDec*100)/255)+ "%" );

Page 105: ProjecteOscar-memoria

105

if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(69)==49) contDom .enviar( "0146" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField46().setText(Integer. toString(valorDec-40)+ "ºC" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(70)==49) contDom .enviar( "0147" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField47().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(71)==49) contDom .enviar( "0148" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField48().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(72)==49) contDom .enviar( "0149" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField49().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(73)==49) contDom .enviar( "014A" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField4A().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(74)==49)

Page 106: ProjecteOscar-memoria

106

contDom .enviar( "014B" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField4B().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(75)==49) contDom .enviar( "014C" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField4C().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(76)==49) contDom .enviar( "014D" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField4D().setText(Integer. toString((a*256)+b)+ "min" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(77)==49) contDom .enviar( "014E" ); int a=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); int b=Integer. parseInt( contDom .devuelvePid().substring(10,12), 16); VMed.getJTextField4E().setText(Integer. toString((a*256)+b)+ "min" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(80)==49) contDom .enviar( "0151" ); if( contDom .devuelvePid().substring(7,9).compareTo( "01" )==0) VMed.getJTextField51().setText( "Gasoline" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "02" )==0) VMed.getJTextField51().setText( "Methanol" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "03" )==0) VMed.getJTextField51().setText( "Ethanol" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "04" )==0) VMed.getJTextField51().setText( "Diesel" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "05" )==0) VMed.getJTextField51().setText( "LPG" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "06" )==0) VMed.getJTextField51().setText( "CNG"); else if( contDom .devuelvePid().substring(7,9).compareTo( "07" )==0) VMed.getJTextField51().setText( "Propane" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "08" )==0) VMed.getJTextField51().setText( "Electric" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "09" )==0) VMed.getJTextField51().setText( "Bifuel running Gasoline" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "0A" )==0) VMed.getJTextField51().setText( "Bifuel running Methanol" );

Page 107: ProjecteOscar-memoria

107

else if( contDom .devuelvePid().substring(7,9).compareTo( "0B" )==0) VMed.getJTextField51().setText( "Bifuel running Ethanol" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "0C" )==0) VMed.getJTextField51().setText( "Bifuel running LPG" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "0D" )==0) VMed.getJTextField51().setText( "Bifuel running CNG" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "0E" )==0) VMed.getJTextField51().setText( "Bifuel running Propane" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "0F" )==0) VMed.getJTextField51().setText( "Bifuel running Electricity" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "10" )==0) VMed.getJTextField51().setText( "Bifuel mixed gas/electric" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "11" )==0) VMed.getJTextField51().setText( "Hybrid gasoline" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "12" )==0) VMed.getJTextField51().setText( "Hybrid Ethanol" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "13" )==0) VMed.getJTextField51().setText( "Hybrid Diesel" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "14" )==0) VMed.getJTextField51().setText( "Hybrid Electric" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "15" )==0) VMed.getJTextField51().setText( "Hybrid Mixed fuel" ); else if( contDom .devuelvePid().substring(7,9).compareTo( "16" )==0) VMed.getJTextField51().setText( "Hybrid Regenerative" ); if( pararHilo ==true) indica_hilo_destruido =true; break; if( pids_disponibles .codePointAt(81)==49) contDom .enviar( "0152" ); int valorDec=Integer. parseInt( contDom .devuelvePid().substring(7,9), 16); VMed.getJTextField52().setText( df .format((valorDec*100)/255)+ "%" ); if( pararHilo ==true) indica_hilo_destruido =true; break;

Clase ControladorPrincipal:

package Presentacion; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import Dominio.ControladorDominioConexion; public class ControladorPrincipal VistaPrincipal VP; ControladorDominioConexion contDomCon ; ControladorPSerie cP; ControladorProtocolo cProt ;

Page 108: ProjecteOscar-memoria

108

ControladorMediciones cMed; ControladorErrores cErr ; JPanel panel ; JLabel labelImagen ; boolean existe_panel =false; boolean existe_label =true; public ControladorPrincipal() VP = new VistaPrincipal(); contDomCon = new ControladorDominioConexion( VP.getJTextArea()); cP = new ControladorPSerie( contDomCon ); cProt = new ControladorProtocolo( contDomCon ); cMed = new ControladorMediciones( contDomCon ); cErr = new ControladorErrores( contDomCon , cMed); labelImagen = new JLabel(); labelImagen .setSize(791, 677); labelImagen .setIcon ( new ImageIcon( "VisualOBD4_1.jpg" )); VP.getJContentPane().add( labelImagen , null); VP.initialize(); public void inicializar() VP.getJButtonConectar().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) contDomCon .establecerConexion( cP.cojerDatosConexion().getVelocidad(), cP.cojerDatosConexion().getDataBits(), cP.cojerDatosConexion().getStopBits(), cP.cojerDatosConexion().getParidad(), cP.cojerDatosConexion().getNombrePuerto(), cProt .fijar_protocolo()); cMed. pararHilo =false; cMed. inicializacion =true; cMed. conectado =true; ); VP.getJButtonDesconectar().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) cMed. pararHilo =true; cMed. conectado =false; if( cMed. lectura ==true) while( cMed. indica_hilo_destruido ==false) try Thread. sleep(10); catch (InterruptedException des) des.printStackTrace(); contDomCon .desconectar(); else contDomCon .desconectar(); cMed. lectura =false; ); VP.getJMenuItemPSerie().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) if( existe_panel ==true) VP.getJContentPane().remove( panel ); if( existe_label ==true) VP.getJContentPane().remove( labelImagen );

Page 109: ProjecteOscar-memoria

109

panel = cP.retornaPanel(); VP.getJContentPane().add( panel , null); existe_panel =true; VP.initialize(); ); VP.getJMenuItemProtocolo().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) if( existe_panel ==true) VP.getJContentPane().remove( panel ); if( existe_label ==true) VP.getJContentPane().remove( labelImagen ); panel = cProt .devuelve_panel(); VP.getJContentPane().add( panel , null); existe_panel =true; VP.initialize(); ); VP.getJMenuItemErrores().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) if( existe_panel ==true) VP.getJContentPane().remove( panel ); if( existe_label ==true) VP.getJContentPane().remove( labelImagen ); panel = cErr .devuelve_panel(); VP.getJContentPane().add( panel , null); existe_panel =true; VP.initialize(); ); VP.getJMenuItemLectura().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) if( existe_panel ==true) VP.getJContentPane().remove( panel ); if( existe_label ==true) VP.getJContentPane().remove( labelImagen ); panel = cMed.devuelve_panel(); VP.getJContentPane().add( panel , null); existe_panel =true; VP.initialize(); ); VP.getJMenuItemPresentacion().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) if( existe_panel ==true) VP.getJContentPane().remove( panel ); if( existe_label ==true) VP.getJContentPane().remove( labelImagen ); labelImagen .setSize(791, 677); labelImagen .setIcon ( new ImageIcon( "VisualOBD4_1.jpg" )); VP.getJContentPane().add( labelImagen , null); existe_label =true; VP.initialize(); );

Page 110: ProjecteOscar-memoria

110

VP.getJMenuItemExit().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) System. exit(0); ); VP.getJButtonEnvioManual().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) contDomCon .permiteEnvioManual( true); contDomCon .enviar( VP.getJTextFieldEnvioManual().getText()); VP.getJTextFieldEnvioManual().setText( "" ); ); VP.getJTextFieldEnvioManual().addKeyListener( new java.awt.event.KeyAdapter() public void keyPressed(java.awt.event.KeyEvent e) if(e.getKeyCode()==10) VP.getJButtonEnvioManual().doClick(); ); VP.addWindowListener( new java.awt.event.WindowAdapter() public void windowClosing(java.awt.event.WindowEvent e) System. exit(0); ); VP.getJMenuItemAbout().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) if( existe_panel ==true) VP.getJContentPane().remove( panel ); if( existe_label ==true) VP.getJContentPane().remove( labelImagen ); labelImagen .setSize(791, 677); labelImagen .setIcon ( new ImageIcon( "AboutVisualOBD.jpg" )); VP.getJContentPane().add( labelImagen , null); existe_label =true; VP.initialize(); ); public static void main (String args[]) ControladorPrincipal conPrin = new ControladorPrincipal(); conPrin.inicializar();

Clase ControladorProtocolo:

package Presentacion; import javax.swing.JPanel; import Dominio.ControladorDominioConexion;

Page 111: ProjecteOscar-memoria

111

public class ControladorProtocolo VistaProtocolo VProt ; String protocolo ; ControladorDominioConexion contDom ; public ControladorProtocolo(ControladorDominioConexion co ntDom) VProt = new VistaProtocolo(); this. contDom = contDom; eventos(); public String fijar_protocolo() if( VProt .getJRadioButtonAutomatico().isSelected()== true) protocolo ="atsp0" ; if( VProt .getJRadioButtonPWM().isSelected()== true) protocolo ="atsp1" ; if( VProt .getJRadioButtonVPW().isSelected()== true) protocolo ="atsp2" ; if( VProt .getJRadioButtonISO().isSelected()== true) protocolo ="atsp3" ; if( VProt .getJRadioButtonKWP1().isSelected()== true) protocolo ="atsp4" ; if( VProt .getJRadioButtonKWP2().isSelected()== true) protocolo ="atsp5" ; if( VProt .getJRadioButtonCAN1().isSelected()== true) protocolo ="atsp6" ; if( VProt .getJRadioButtonCAN2().isSelected()== true) protocolo ="atsp7" ; if( VProt .getJRadioButtonCAN3().isSelected()== true) protocolo ="atsp8" ; if( VProt .getJRadioButtonCAN4().isSelected()== true) protocolo ="atsp9" ; return protocolo ; public JPanel devuelve_panel() return this. VProt ; public void eventos() VProt .getJComboBoxPrio1().setEnabled( false); VProt .getJComboBoxPrio2().setEnabled( false); VProt .getJComboBoxRec1().setEnabled( false); VProt .getJComboBoxRec2().setEnabled( false); VProt .getJComboBoxTran1().setEnabled( false); VProt .getJComboBoxTran2().setEnabled( false); VProt .getJButtonAplByHead().setVisible( false); VProt .getJButtonAplByHead().addMouseListener( new java.awt.event.MouseAdapter() public void mousePressed(java.awt.event.MouseEvent e)

Page 112: ProjecteOscar-memoria

112

contDom .enviar( "atsh " +VProt .getJComboBoxPrio1().getSelectedItem()+ VProt .getJComboBoxPrio2().getSelectedItem()+ " " +VProt .getJComboBoxRec1().getSelectedItem()+ VProt .getJComboBoxRec2().getSelectedItem()+ " " +VProt .getJComboBoxTran1().getSelectedItem()+ VProt .getJComboBoxTran2().getSelectedItem()); ); VProt .getJCheckBoxIntroHead().addMouseListener( new java.awt.event.MouseAdapter() public void mouseClicked(java.awt.event.MouseEvent e) if( VProt .getJCheckBoxIntroHead().isSelected()== true) VProt .getJComboBoxPrio1().setEnabled( true); VProt .getJComboBoxPrio2().setEnabled( true); VProt .getJComboBoxRec1().setEnabled( true); VProt .getJComboBoxRec2().setEnabled( true); VProt .getJComboBoxTran1().setEnabled( true); VProt .getJComboBoxTran2().setEnabled( true); VProt .getJButtonAplByHead().setVisible( true); else VProt .getJComboBoxPrio1().setEnabled( false); VProt .getJComboBoxPrio2().setEnabled( false); VProt .getJComboBoxRec1().setEnabled( false); VProt .getJComboBoxRec2().setEnabled( false); VProt .getJComboBoxTran1().setEnabled( false); VProt .getJComboBoxTran2().setEnabled( false); VProt .getJButtonAplByHead().setVisible( false); );

Page 113: ProjecteOscar-memoria

113

Clase ControladorPSerie:

package Presentacion; import javax.swing.JPanel; import Datos.Conexion; import Dominio.ControladorDominioConexion; public class ControladorPSerie VistaConfiguracio VC; Conexion con ; ControladorDominioConexion contDom ; public ControladorPSerie(ControladorDominioConexion contD om) VC = new VistaConfiguracio(); this. contDom = contDom; eventos(); datosconexion(); public void eventos() VC.getJButtonIdentificarPuertos().addMouseListener( new java.awt.event.MouseAdapter() public void mouseClicked(java.awt.event.MouseEvent e) puertosDisponibles(); ); VC.getJButtonAplicar().addActionListener( new java.awt.event.ActionListener() public void actionPerformed(java.awt.event.ActionEvent e) try if( contDom .estado_conexion()== true) contDom .desconectar(); datosconexion(); catch(Exception err) ); public JPanel retornaPanel() return this. VC; public void puertosDisponibles() VC.getJListListaPuertos().setListData( contDom .puertosdisponibles()); public Conexion cojerDatosConexion() return con ; public void datosconexion() con = new Conexion(Integer. parseInt((String) VC.getJComboBoxVelocidad().getSelectedItem()),Integer . parseInt((String) VC.getJComboBoxDataBits().getSelectedItem()),( VC.getJComboBoxStopBits().getSelectedIndex())+1, VC.getJComboBoxParidad().getSelectedIndex(), VC.getJComboBoxNombrePort().getSelectedItem().toString(), "0100" );

Page 114: ProjecteOscar-memoria

114

Clase VistaCodigosError:

package Presentacion; import java.awt.Dimension; import java.awt.Font; import javax.swing.JPanel; import javax.swing.JTextArea; import java.awt.Rectangle; import javax.swing.JButton; import javax.swing.JScrollPane; public class VistaCodigosError extends JPanel private static final long serialVersionUID = 1L; private JTextArea jTextAreaErrores = null; private JButton jButtonErrores = null; private JScrollPane jScrollPaneErrores = null; private JButton jButtonBorrarErrores = null;

public VistaCodigosError() super(); initialize(); private void initialize() this.setSize( new Dimension(800, 677)); this.setLayout( null); this.add(getJTextAreaErrores(), null); this.add(getJButtonErrores(), null); this.add(getJScrollPaneErrores(), null); this.add(getJButtonBorrarErrores(), null); public JTextArea getJTextAreaErrores() if ( jTextAreaErrores == null) jTextAreaErrores = new JTextArea(); jTextAreaErrores .setBounds( new Rectangle(77, 88, 182, 155)); jTextAreaErrores .setFont( new Font( "Dialog" , Font. BOLD, 19)); jTextAreaErrores .setEditable( false); return jTextAreaErrores ; public JButton getJButtonErrores() if ( jButtonErrores == null) jButtonErrores = new JButton(); jButtonErrores .setBounds( new Rectangle(7, 650, 177, 20)); jButtonErrores .setText( "Read error codes" ); return jButtonErrores ; private JScrollPane getJScrollPaneErrores() if ( jScrollPaneErrores == null) jScrollPaneErrores = new JScrollPane(getJTextAreaErrores(),JScrollPane. VERTICAL_SCROLLBAR_ALWAYS,JScrollPane. HORIZONTAL_SCROLLBAR_ALWAYS); jScrollPaneErrores .setBounds( new Rectangle(7, 7, 784, 637)); return jScrollPaneErrores ;

Page 115: ProjecteOscar-memoria

115

public JButton getJButtonBorrarErrores() if ( jButtonBorrarErrores == null) jButtonBorrarErrores = new JButton(); jButtonBorrarErrores .setBounds( new Rectangle(183, 650, 183, 20)); jButtonBorrarErrores .setText( "Clear error codes" ); return jButtonBorrarErrores ;

Clase VistaConfiguracion:

package Presentacion; import javax.swing.JPanel; import java.awt.Dimension; import javax.swing.JComboBox; import java.awt.Rectangle; import java.awt.Color; import java.awt.Point; import javax.swing.JLabel; import java.awt.Font; import javax.swing.JButton; import javax.swing.JList; import javax.swing.JScrollPane;

public class VistaConfiguracion extends JPanel private static final long serialVersionUID = 1L; private JComboBox jComboBoxNombrePort = null; private JComboBox jComboBoxDataBits = null; private JComboBox jComboBoxStopBits = null; private JComboBox jComboBoxParidad = null; private JComboBox jComboBoxVelocidad = null; private JLabel jLabelTituloPserie = null; private JLabel jLabelVelocidad = null; private JLabel jLabelNombrePuerto = null; private JLabel jLabelBitsDatos = null; private JLabel jLabelBitsStop = null; private JLabel jLabelParidad = null; private JButton jButtonAplicar = null; private JButton jButtonIdentificarPuertos = null; String [] puertos = "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "COM10", "COM11", "COM12", "/dev/ttyS0" , "/dev/ttyS1" , "/dev/ttyACM0" , "/dev/ttyACM1" , "/dev/ttyUSB0" , "/dev/ttyUSB1" ; String [] velocidad = "75" , "110" , "134" , "150" , "300" , "600" , "1200" , "1800" , "2400" , "4800" , "7200" , "9600" , "14400" , "19200" , "38400" , "57600" , "115200" , "128000" ; String [] bitsDatos = "4" , "5" , "6" , "7" , "8" ; String [] paridad = "Ninguno" , "Impar" , "Par" , "Marca" , "Espacio" ; String [] bitsParada = "1" , "2" , "1,5" ; private JList jListListaPuertos = null; private JScrollPane jScrollPaneListaPuertos = null; public VistaConfiguracion() super(); initialize();

Page 116: ProjecteOscar-memoria

116

private void initialize() jLabelParidad = new JLabel(); jLabelParidad .setBounds( new Rectangle(30, 385, 68, 17)); jLabelParidad .setText( "Parity:" ); jLabelParidad .setFont( new Font( "Dialog" , Font. BOLD, 14)); jLabelBitsStop = new JLabel(); jLabelBitsStop .setBounds( new Rectangle(30, 310, 90, 17)); jLabelBitsStop .setText( "Stop bits:" ); jLabelBitsStop .setFont( new Font( "Dialog" , Font. BOLD, 14)); jLabelBitsDatos = new JLabel(); jLabelBitsDatos .setBounds( new Rectangle(30, 235, 88, 17)); jLabelBitsDatos .setText( "Data bits:" ); jLabelBitsDatos .setFont( new Font( "Dialog" , Font. BOLD, 14)); jLabelNombrePuerto = new JLabel(); jLabelNombrePuerto .setBounds( new Rectangle(30, 85, 122, 17)); jLabelNombrePuerto .setText( "Port Identifier:" ); jLabelNombrePuerto .setFont( new Font( "Dialog" , Font. BOLD, 14)); jLabelVelocidad = new JLabel(); jLabelVelocidad .setBounds( new Rectangle(30, 160, 79, 17)); jLabelVelocidad .setText( "Bit rate:" ); jLabelVelocidad .setFont( new Font( "Dialog" , Font. BOLD, 14)); jLabelTituloPserie = new JLabel(); jLabelTituloPserie .setBounds( new Rectangle(30, 25, 257, 26)); jLabelTituloPserie .setFont( new Font( "Dialog" , Font. BOLD, 18)); jLabelTituloPserie .setText( "Serial port configuration" ); this.setLayout( null); this.setBackground( new Color(238, 238, 238)); this.setLocation( new Point(0, 0)); this.setSize( new Dimension(800, 675)); this.add(getJComboBoxNombrePort(), null); this.add(getJComboBoxDataBits(), null); this.add(getJComboBoxStopBits(), null); this.add(getJComboBoxParidad(), null); this.add(getJComboBoxVelocidad(), null); this.add( jLabelTituloPserie , null); this.add( jLabelVelocidad , null); this.add( jLabelNombrePuerto , null); this.add( jLabelBitsDatos , null); this.add( jLabelBitsStop , null); this.add( jLabelParidad , null); this.add(getJButtonAplicar(), null); this.add(getJButtonIdentificarPuertos(), null); this.add(getJScrollPaneListaPuertos(), null); public JComboBox getJComboBoxNombrePort() if ( jComboBoxNombrePort == null) jComboBoxNombrePort = new JComboBox( puertos ); jComboBoxNombrePort .setBounds( new Rectangle(30, 105, 135, 25)); jComboBoxNombrePort .setSelectedIndex(0); return jComboBoxNombrePort ;

public JComboBox getJComboBoxDataBits() if ( jComboBoxDataBits == null) jComboBoxDataBits = new JComboBox( bitsDatos ); jComboBoxDataBits .setBounds( new Rectangle(30, 255, 135, 25)); jComboBoxDataBits .setSelectedIndex(4); return jComboBoxDataBits ;

Page 117: ProjecteOscar-memoria

117

public JComboBox getJComboBoxStopBits() if ( jComboBoxStopBits == null) jComboBoxStopBits = new JComboBox( bitsParada ); jComboBoxStopBits .setBounds( new Rectangle(30, 330, 135, 25)); jComboBoxStopBits .setSelectedIndex(0); return jComboBoxStopBits ; public JComboBox getJComboBoxParidad() if ( jComboBoxParidad == null) jComboBoxParidad = new JComboBox( paridad ); jComboBoxParidad .setBounds( new Rectangle(30, 405, 135, 25)); jComboBoxParidad .setSelectedIndex(0); return jComboBoxParidad ; public JComboBox getJComboBoxVelocidad() if ( jComboBoxVelocidad == null) jComboBoxVelocidad = new JComboBox( velocidad ); jComboBoxVelocidad .setBounds( new Rectangle(30, 180, 135, 25)); jComboBoxVelocidad .setSelectedIndex(14); return jComboBoxVelocidad ; public JButton getJButtonAplicar() if ( jButtonAplicar == null) jButtonAplicar = new JButton(); jButtonAplicar .setBounds( new Rectangle(30, 648, 115, 20)); jButtonAplicar .setText( "Apply" ); return jButtonAplicar ; public JButton getJButtonIdentificarPuertos() if ( jButtonIdentificarPuertos == null) jButtonIdentificarPuertos = new JButton(); jButtonIdentificarPuertos .setBounds( new Rectangle(30, 520, 209, 19)); jButtonIdentificarPuertos .setText( "Search for available ports" ); return jButtonIdentificarPuertos ; public JList getJListListaPuertos() if ( jListListaPuertos == null) jListListaPuertos = new JList(); jListListaPuertos .setEnabled( false); jListListaPuertos .setFont( new Font( "Dialog" , Font. BOLD, 12)); return jListListaPuertos ; private JScrollPane getJScrollPaneListaPuertos() if ( jScrollPaneListaPuertos == null) jScrollPaneListaPuertos = new JScrollPane(); jScrollPaneListaPuertos .setBounds( new Rectangle(30, 540, 209, 58)); jScrollPaneListaPuertos .setViewportView(getJListListaPuertos()); return jScrollPaneListaPuertos ;

Page 118: ProjecteOscar-memoria

118

Clase VistaMediciones:

package Presentacion; import java.awt.Color; import java.awt.Font; import javax.swing.JPanel; import javax.swing.JTabbedPane; import java.awt.Rectangle; import javax.swing.JTextField; import javax.swing.JLabel; import javax.swing.JButton; public class VistaMediciones extends JPanel private static final long serialVersionUID = 1L; private JTabbedPane jTabbedPane = null; private JPanel jPanel4_19 = null; private JPanel jPanel21_40 = null; private JPanel jPanel41_60 = null; private JTextField jTextField04 = null; private JTextField jTextField05 = null; private JTextField jTextField06 = null; private JTextField jTextField07 = null; private JTextField jTextField08 = null; private JTextField jTextField09 = null; private JTextField jTextField0A = null; private JTextField jTextField0B = null; private JTextField jTextField0C = null; private JTextField jTextField0D = null; private JTextField jTextField0E = null; private JTextField jTextField0F = null; private JTextField jTextField10 = null; private JTextField jTextField11 = null; private JTextField jTextField12 = null; private JTextField jTextField14 = null; private JTextField jTextField15 = null; private JTextField jTextField16 = null; private JTextField jTextField17 = null; private JTextField jTextField18 = null; private JTextField jTextField19 = null; private JTextField jTextField1A = null; private JTextField jTextField1B = null; private JTextField jTextField1E = null; private JTextField jTextField1F = null; private JTextField jTextField24 = null; private JTextField jTextField25 = null; private JTextField jTextField26 = null; private JTextField jTextField27 = null; private JTextField jTextField28 = null; private JTextField jTextField29 = null; private JTextField jTextField2A = null; private JTextField jTextField2B = null; private JTextField jTextField2C = null; private JTextField jTextField2D = null; private JTextField jTextField2E = null; private JTextField jTextField2F = null; private JTextField jTextField33 = null; private JTextField jTextField31 = null; private JTextField jTextField32 = null; private JTextField jTextField34 = null; private JTextField jTextField35 = null; private JTextField jTextField36 = null;

Page 119: ProjecteOscar-memoria

119

private JTextField jTextField37 = null; private JTextField jTextField38 = null; private JTextField jTextField39 = null; private JTextField jTextField3A = null; private JTextField jTextField3B = null; private JTextField jTextField3E = null; private JTextField jTextField3F = null; private JLabel jLabel04 = null; private JLabel jLabel05 = null; private JLabel jLabel06 = null; private JLabel jLabel07 = null; private JLabel jLabel08 = null; private JLabel jLabel09 = null; private JLabel jLabel0A = null; private JLabel jLabel0B = null; private JLabel jLabel0C = null; private JLabel jLabel0D = null; private JLabel jLabel0E = null; private JLabel jLabel0F = null; private JLabel jLabel10 = null; private JLabel jLabel11 = null; private JLabel jLabel12 = null; private JLabel jLabel14 = null; private JLabel jLabel15 = null; private JLabel jLabel16 = null; private JLabel jLabel18 = null; private JLabel jLabel19 = null; private JLabel jLabel17 = null; private JLabel jLabel1A = null; private JLabel jLabel1E = null; private JLabel jLabel1B = null; private JLabel jLabel1F = null; private JLabel jLabel24 = null; private JLabel jLabel25 = null; private JLabel jLabel26 = null; private JLabel jLabel27 = null; private JLabel jLabel28 = null; private JLabel jLabel29 = null; private JLabel jLabel2A = null; private JLabel jLabel2B = null; private JLabel jLabel2C = null; private JLabel jLabel2D = null; private JLabel jLabel2E = null; private JLabel jLabel2F = null; private JLabel jLabel33 = null; private JLabel jLabel31 = null; private JLabel jLabel32 = null; private JLabel jLabel34 = null; private JLabel jLabel35 = null; private JLabel jLabel36 = null; private JLabel jLabel38 = null; private JLabel jLabel39 = null; private JLabel jLabel37 = null; private JLabel jLabel3A = null; private JLabel jLabel3E = null; private JLabel jLabel3B = null; private JLabel jLabel3F = null; private JLabel jLabel12_1 = null; private JLabel jLabel12_2 = null; private JLabel jLabelSensores = null; private JTextField jTextField21 = null; private JTextField jTextField22 = null; private JTextField jTextField23 = null;

Page 120: ProjecteOscar-memoria

120

private JLabel jLabel21 = null; private JLabel jLabel22 = null; private JLabel jLabel23 = null; private JLabel jLabel21_1 = null; private JTextField jTextField3C = null; private JTextField jTextField3D = null; private JLabel jLabel3C = null; private JLabel jLabel3D = null; private JButton jButtonLeer = null; private JButton jButtonDetener = null; private JTextField jTextField42 = null; private JTextField jTextField43 = null; private JTextField jTextField44 = null; private JTextField jTextField45 = null; private JTextField jTextField46 = null; private JTextField jTextField47 = null; private JTextField jTextField48 = null; private JTextField jTextField49 = null; private JTextField jTextField4A = null; private JTextField jTextField4B = null; private JTextField jTextField4C = null; private JTextField jTextField4D = null; private JTextField jTextField4E = null; private JLabel jLabel42 = null; private JLabel jLabel43 = null; private JLabel jLabel44 = null; private JLabel jLabel45 = null; private JLabel jLabel46 = null; private JLabel jLabel47 = null; private JLabel jLabel48 = null; private JLabel jLabel49 = null; private JLabel jLabel4A = null; private JLabel jLabel4B = null; private JLabel jLabel4C = null; private JLabel jLabel4D = null; private JLabel jLabel4E = null; private JTextField jTextField51 = null; private JLabel jLabel51 = null; private JLabel jLabel52 = null; private JTextField jTextField52 = null; private JTextField jTextField1C = null; private JLabel jLabel1C = null; public VistaMediciones() super(); initialize(); private void initialize() this.setSize(803, 676); this.setLayout( null); this.add(getJTabbedPane(), null); this.add(getJButtonLeer(), null); this.add(getJButtonDetener(), null);

private JTabbedPane getJTabbedPane() if ( jTabbedPane == null) jTabbedPane = new JTabbedPane(); jTabbedPane .setBounds( new Rectangle(6, 6, 788, 638)); jTabbedPane .addTab( " PID's 4-19 " , null, getJPanel4_19(), null);

Page 121: ProjecteOscar-memoria

121

jTabbedPane .addTab( " PID's 21-40 " , null, getJPanel21_40(), null); jTabbedPane .addTab( " PID's 41-60 " , null, getJPanel41_60(), null); return jTabbedPane ; private JPanel getJPanel4_19() if ( jPanel4_19 == null) jLabel1C = new JLabel(); jLabel1C .setBounds( new Rectangle(5, 505, 287, 16)); jLabel1C .setFont( new Font( "Dialog" , Font. BOLD, 14)); jLabel1C .setText( "This vehicle conforms the standards:" ); jLabelSensores = new JLabel(); jLabelSensores .setBounds( new Rectangle(380, 145, 335, 17)); jLabelSensores .setText( "Oxygen sensor voltage, Short term fuel trim" ); jLabelSensores .setFont( new Font( "Dialog" , Font. BOLD, 14)); jLabel12_2 = new JLabel(); jLabel12_2 .setBounds( new Rectangle(675, 121, 78, 17)); jLabel12_2 .setText( "air status" ); jLabel12_2 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel12_1 = new JLabel(); jLabel12_1 .setBounds( new Rectangle(675, 103, 85, 17)); jLabel12_1 .setText( "secondary" ); jLabel12_1 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel1F = new JLabel(); jLabel1F .setBounds( new Rectangle(525, 525, 198, 17)); jLabel1F .setText( "Run time since engine start" ); jLabel1F .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel1B = new JLabel(); jLabel1B .setBounds( new Rectangle(525, 445, 138, 17)); jLabel1B .setText( "Bank 2, Sensor 4" ); jLabel1B .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel1E = new JLabel(); jLabel1E .setBounds( new Rectangle(525, 485, 152, 17)); jLabel1E .setText( "Auxiliary input status" ); jLabel1E .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel1A = new JLabel(); jLabel1A .setBounds( new Rectangle(525, 405, 138, 17)); jLabel1A .setText( "Bank 2, Sensor 3" ); jLabel1A .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel17 = new JLabel(); jLabel17 .setBounds( new Rectangle(525, 285, 136, 17)); jLabel17 .setText( "Bank 1, Sensor 4" ); jLabel17 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel19 = new JLabel(); jLabel19 .setBounds( new Rectangle(525, 365, 138, 17)); jLabel19 .setText( "Bank 2, Sensor 2" ); jLabel19 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel18 = new JLabel(); jLabel18 .setBounds( new Rectangle(525, 325, 136, 17)); jLabel18 .setText( "Bank 2, Sensor 1" ); jLabel18 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel16 = new JLabel(); jLabel16 .setBounds( new Rectangle(525, 245, 136, 17)); jLabel16 .setText( "Bank 1, Sensor 3" ); jLabel16 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel15 = new JLabel(); jLabel15 .setBounds( new Rectangle(525, 205, 134, 17)); jLabel15 .setText( "Bank 1, Sensor 2" ); jLabel15 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel14 = new JLabel();

Page 122: ProjecteOscar-memoria

122

jLabel14 .setBounds( new Rectangle(525, 165, 133, 17)); jLabel14 .setText( "Bank 1, Sensor 1" ); jLabel14 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel12 = new JLabel(); jLabel12 .setBounds( new Rectangle(675, 85, 99, 17)); jLabel12 .setText( "Commanded " ); jLabel12 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel11 = new JLabel(); jLabel11 .setBounds( new Rectangle(525, 45, 132, 17)); jLabel11 .setText( "Throttle position" ); jLabel11 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel10 = new JLabel(); jLabel10 .setBounds( new Rectangle(525, 5, 132, 17)); jLabel10 .setText( "MAF air flow rate" ); jLabel10 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel0F = new JLabel(); jLabel0F .setBounds( new Rectangle(150, 445, 167, 17)); jLabel0F .setText( "Intake air temperature" ); jLabel0F .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel0E = new JLabel(); jLabel0E .setBounds( new Rectangle(150, 405, 133, 17)); jLabel0E .setText( "Timing advance" ); jLabel0E .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel0D = new JLabel(); jLabel0D .setBounds( new Rectangle(150, 365, 120, 17)); jLabel0D .setText( "Vehicle speed" ); jLabel0D .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel0C = new JLabel(); jLabel0C .setBounds( new Rectangle(150, 325, 104, 17)); jLabel0C .setText( "Engine RPM" ); jLabel0C .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel0B = new JLabel(); jLabel0B .setBounds( new Rectangle(150, 285, 186, 17)); jLabel0B .setText( "Intake manifold pressure" ); jLabel0B .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel0A = new JLabel(); jLabel0A .setBounds( new Rectangle(150, 245, 118, 17)); jLabel0A .setText( "Fuel pressure" ); jLabel0A .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel09 = new JLabel(); jLabel09 .setBounds( new Rectangle(150, 205, 225, 17)); jLabel09 .setText( "Long term fuel % trim_Bank 2" ); jLabel09 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel08 = new JLabel(); jLabel08 .setBounds( new Rectangle(150, 165, 226, 17)); jLabel08 .setText( "Short term fuel % trim_Bank 2" ); jLabel08 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel07 = new JLabel(); jLabel07 .setBounds( new Rectangle(150, 125, 225, 17)); jLabel07 .setText( "Long term fuel % trim_Bank 1" ); jLabel07 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel06 = new JLabel(); jLabel06 .setBounds( new Rectangle(150, 85, 224, 17)); jLabel06 .setText( "Short term fuel % trim_Bank 1" ); jLabel06 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel05 = new JLabel(); jLabel05 .setBounds( new Rectangle(150, 45, 207, 17)); jLabel05 .setText( "Engine coolant temperature" ); jLabel05 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel04 = new JLabel(); jLabel04 .setBounds( new Rectangle(150, 5, 206, 17)); jLabel04 .setText( "Calculated engine load value" ); jLabel04 .setFont( new Font( "Dialog" , Font. PLAIN, 14));

Page 123: ProjecteOscar-memoria

123

jPanel4_19 = new JPanel(); jPanel4_19 .setLayout( null); jPanel4_19 .add(getJTextField04(), null); jPanel4_19 .add(getJTextField05(), null); jPanel4_19 .add(getJTextField06(), null); jPanel4_19 .add(getJTextField07(), null); jPanel4_19 .add(getJTextField08(), null); jPanel4_19 .add(getJTextField09(), null); jPanel4_19 .add(getJTextField0A(), null); jPanel4_19 .add(getJTextField0B(), null); jPanel4_19 .add(getJTextField0C(), null); jPanel4_19 .add(getJTextField0D(), null); jPanel4_19 .add(getJTextField0E(), null); jPanel4_19 .add(getJTextField0F(), null); jPanel4_19 .add(getJTextField10(), null); jPanel4_19 .add(getJTextField11(), null); jPanel4_19 .add(getJTextField12(), null); jPanel4_19 .add(getJTextField14(), null); jPanel4_19 .add(getJTextField15(), null); jPanel4_19 .add(getJTextField16(), null); jPanel4_19 .add(getJTextField17(), null); jPanel4_19 .add(getJTextField18(), null); jPanel4_19 .add(getJTextField19(), null); jPanel4_19 .add(getJTextField1A(), null); jPanel4_19 .add(getJTextField1B(), null); jPanel4_19 .add(getJTextField1E(), null); jPanel4_19 .add(getJTextField1F(), null); jPanel4_19 .add( jLabel04 , null); jPanel4_19 .add( jLabel05 , null); jPanel4_19 .add( jLabel06 , null); jPanel4_19 .add( jLabel07 , null); jPanel4_19 .add( jLabel08 , null); jPanel4_19 .add( jLabel09 , null); jPanel4_19 .add( jLabel0A , null); jPanel4_19 .add( jLabel0B , null); jPanel4_19 .add( jLabel0C , null); jPanel4_19 .add( jLabel0D , null); jPanel4_19 .add( jLabel0E , null); jPanel4_19 .add( jLabel0F , null); jPanel4_19 .add( jLabel10 , null); jPanel4_19 .add( jLabel11 , null); jPanel4_19 .add( jLabel12 , null); jPanel4_19 .add( jLabel14 , null); jPanel4_19 .add( jLabel15 , null); jPanel4_19 .add( jLabel16 , null); jPanel4_19 .add( jLabel18 , null); jPanel4_19 .add( jLabel19 , null); jPanel4_19 .add( jLabel17 , null); jPanel4_19 .add( jLabel1A , null); jPanel4_19 .add( jLabel1E , null); jPanel4_19 .add( jLabel1B , null); jPanel4_19 .add( jLabel1F , null); jPanel4_19 .add( jLabel12_1 , null); jPanel4_19 .add( jLabel12_2 , null); jPanel4_19 .add( jLabelSensores , null); jPanel4_19 .add(getJTextField1C(), null); jPanel4_19 .add( jLabel1C , null); return jPanel4_19 ;

Page 124: ProjecteOscar-memoria

124

private JPanel getJPanel21_40() if ( jPanel21_40 == null) jLabel3D = new JLabel(); jLabel3D .setBounds( new Rectangle(525, 485, 258, 16)); jLabel3D .setText( "Catalyst Temperature Bank2, Sensor1" ); jLabel3D .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel3C = new JLabel(); jLabel3C .setBounds( new Rectangle(525, 445, 258, 16)); jLabel3C .setText( "Catalyst Temperature Bank1, Sensor1" ); jLabel3C .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel21_1 = new JLabel(); jLabel21_1 .setBounds( new Rectangle(145, 23, 166, 17)); jLabel21_1 .setText( "indicator lamp (MIL) on" ); jLabel21_1 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel23 = new JLabel(); jLabel23 .setBounds( new Rectangle(150, 85, 192, 16)); jLabel23 .setText( "Fuel Rail Pressure (diesel)" ); jLabel23 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel22 = new JLabel(); jLabel22 .setBounds( new Rectangle(150, 45, 170, 17)); jLabel22 .setText( "Fuel Rail Pressure" ); jLabel22 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel21 = new JLabel(); jLabel21 .setBounds( new Rectangle(145, 5, 243, 17)); jLabel21 .setText( "Distance traveled with malfunction" ); jLabel21 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel3F = new JLabel(); jLabel3F .setBounds( new Rectangle(525, 565, 258, 17)); jLabel3F .setText( "Catalyst Temperature Bank2, Sensor2" ); jLabel3F .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel3B = new JLabel(); jLabel3B .setBounds( new Rectangle(525, 405, 221, 17)); jLabel3B .setText( "O2S8_WR_lambda(1): Current" ); jLabel3B .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel3E = new JLabel(); jLabel3E .setBounds( new Rectangle(525, 525, 258, 17)); jLabel3E .setText( "Catalyst Temperature Bank1, Sensor2" ); jLabel3E .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel3A = new JLabel(); jLabel3A .setBounds( new Rectangle(525, 365, 223, 17)); jLabel3A .setText( "O2S7_WR_lambda(1): Current" ); jLabel3A .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel37 = new JLabel(); jLabel37 .setBounds( new Rectangle(525, 245, 220, 17)); jLabel37 .setText( "O2S4_WR_lambda(1): Current" ); jLabel37 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel39 = new JLabel(); jLabel39 .setBounds( new Rectangle(525, 325, 222, 17)); jLabel39 .setText( "O2S6_WR_lambda(1): Current" ); jLabel39 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel38 = new JLabel(); jLabel38 .setBounds( new Rectangle(525, 285, 220, 17)); jLabel38 .setText( "O2S5_WR_lambda(1): Current" ); jLabel38 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel36 = new JLabel(); jLabel36 .setBounds( new Rectangle(525, 205, 221, 17)); jLabel36 .setText( "O2S3_WR_lambda(1): Current" ); jLabel36 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel35 = new JLabel(); jLabel35 .setBounds( new Rectangle(525, 165, 222, 17)); jLabel35 .setText( "O2S2_WR_lambda(1): Current" ); jLabel35 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel34 = new JLabel();

Page 125: ProjecteOscar-memoria

125

jLabel34 .setBounds( new Rectangle(525, 125, 223, 17)); jLabel34 .setText( "O2S1_WR_lambda(1): Current" ); jLabel34 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel32 = new JLabel(); jLabel32 .setBounds( new Rectangle(525, 45, 216, 17)); jLabel32 .setText( "Evap. System Vapor Pressure" ); jLabel32 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel31 = new JLabel(); jLabel31 .setBounds( new Rectangle(525, 5, 257, 17)); jLabel31 .setText( "Distance traveled since codes cleared" ); jLabel31 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel33 = new JLabel(); jLabel33 .setBounds( new Rectangle(525, 85, 159, 17)); jLabel33 .setText( "Barometric pressure" ); jLabel33 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel2F = new JLabel(); jLabel2F .setBounds( new Rectangle(150, 565, 127, 17)); jLabel2F .setText( "Fuel Level Input" ); jLabel2F .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel2E = new JLabel(); jLabel2E .setBounds( new Rectangle(150, 525, 224, 17)); jLabel2E .setText( "Commanded evaporative purge" ); jLabel2E .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel2D = new JLabel(); jLabel2D .setBounds( new Rectangle(150, 485, 89, 17)); jLabel2D .setText( "EGR Error" ); jLabel2D .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel2C = new JLabel(); jLabel2C .setBounds( new Rectangle(150, 445, 153, 17)); jLabel2C .setText( "Commanded EGR"); jLabel2C .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel2B = new JLabel(); jLabel2B .setBounds( new Rectangle(150, 405, 224, 17)); jLabel2B .setText( "O2S8_WR_lambda(1): Voltage" ); jLabel2B .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel2A = new JLabel(); jLabel2A .setBounds( new Rectangle(150, 365, 225, 17)); jLabel2A .setText( "O2S7_WR_lambda(1): Voltage" ); jLabel2A .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel29 = new JLabel(); jLabel29 .setBounds( new Rectangle(150, 325, 226, 17)); jLabel29 .setText( "O2S6_WR_lambda(1): Voltage" ); jLabel29 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel28 = new JLabel(); jLabel28 .setBounds( new Rectangle(150, 285, 225, 17)); jLabel28 .setText( "O2S5_WR_lambda(1): Voltage" ); jLabel28 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel27 = new JLabel(); jLabel27 .setBounds( new Rectangle(150, 245, 225, 17)); jLabel27 .setText( "O2S4_WR_lambda(1): Voltage" ); jLabel27 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel26 = new JLabel(); jLabel26 .setBounds( new Rectangle(150, 205, 227, 17)); jLabel26 .setText( "O2S3_WR_lambda(1): Voltage" ); jLabel26 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel25 = new JLabel(); jLabel25 .setBounds( new Rectangle(150, 165, 225, 17)); jLabel25 .setText( "O2S2_WR_lambda(1): Voltage" ); jLabel25 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel24 = new JLabel(); jLabel24 .setBounds( new Rectangle(150, 125, 227, 17)); jLabel24 .setText( "O2S1_WR_lambda(1): Voltage" ); jLabel24 .setFont( new Font( "Dialog" , Font. PLAIN, 14));

Page 126: ProjecteOscar-memoria

126

jPanel21_40 = new JPanel(); jPanel21_40 .setLayout( null); jPanel21_40 .add(getJTextField24(), null); jPanel21_40 .add(getJTextField25(), null); jPanel21_40 .add(getJTextField26(), null); jPanel21_40 .add(getJTextField27(), null); jPanel21_40 .add(getJTextField28(), null); jPanel21_40 .add(getJTextField29(), null); jPanel21_40 .add(getJTextField2A(), null); jPanel21_40 .add(getJTextField2B(), null); jPanel21_40 .add(getJTextField2C(), null); jPanel21_40 .add(getJTextField2D(), null); jPanel21_40 .add(getJTextField2E(), null); jPanel21_40 .add(getJTextField2F(), null); jPanel21_40 .add(getJTextField33(), null); jPanel21_40 .add(getJTextField31(), null); jPanel21_40 .add(getJTextField32(), null); jPanel21_40 .add(getJTextField34(), null); jPanel21_40 .add(getJTextField35(), null); jPanel21_40 .add(getJTextField36(), null); jPanel21_40 .add(getJTextField37(), null); jPanel21_40 .add(getJTextField38(), null); jPanel21_40 .add(getJTextField39(), null); jPanel21_40 .add(getJTextField3A(), null); jPanel21_40 .add(getJTextField3B(), null); jPanel21_40 .add(getJTextField3E(), null); jPanel21_40 .add(getJTextField3F(), null); jPanel21_40 .add( jLabel24 , null); jPanel21_40 .add( jLabel25 , null); jPanel21_40 .add( jLabel26 , null); jPanel21_40 .add( jLabel27 , null); jPanel21_40 .add( jLabel28 , null); jPanel21_40 .add( jLabel29 , null); jPanel21_40 .add( jLabel2A , null); jPanel21_40 .add( jLabel2B , null); jPanel21_40 .add( jLabel2C , null); jPanel21_40 .add( jLabel2D , null); jPanel21_40 .add( jLabel2E , null); jPanel21_40 .add( jLabel2F , null); jPanel21_40 .add( jLabel33 , null); jPanel21_40 .add( jLabel31 , null); jPanel21_40 .add( jLabel32 , null); jPanel21_40 .add( jLabel34 , null); jPanel21_40 .add( jLabel35 , null); jPanel21_40 .add( jLabel36 , null); jPanel21_40 .add( jLabel38 , null); jPanel21_40 .add( jLabel39 , null); jPanel21_40 .add( jLabel37 , null); jPanel21_40 .add( jLabel3A , null); jPanel21_40 .add( jLabel3E , null); jPanel21_40 .add( jLabel3B , null); jPanel21_40 .add( jLabel3F , null); jPanel21_40 .add(getJTextField21(), null); jPanel21_40 .add(getJTextField22(), null); jPanel21_40 .add(getJTextField23(), null); jPanel21_40 .add( jLabel21 , null); jPanel21_40 .add( jLabel22 , null); jPanel21_40 .add( jLabel23 , null); jPanel21_40 .add( jLabel21_1 , null); jPanel21_40 .add(getJTextField3C(), null); jPanel21_40 .add(getJTextField3D(), null); jPanel21_40 .add( jLabel3C , null); jPanel21_40 .add( jLabel3D , null);

Page 127: ProjecteOscar-memoria

127

return jPanel21_40 ; private JPanel getJPanel41_60() if ( jPanel41_60 == null) jLabel52 = new JLabel(); jLabel52 .setBounds( new Rectangle(525, 85, 123, 19)); jLabel52 .setText( "\tEthanol fuel %" ); jLabel52 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel51 = new JLabel(); jLabel51 .setBounds( new Rectangle(380, 5, 99, 19)); jLabel51 .setText( "Fuel Type:" ); jLabel51 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel4E = new JLabel(); jLabel4E .setBounds( new Rectangle(150, 485, 239, 19)); jLabel4E .setText( "Time since trouble codes cleared" ); jLabel4E .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel4D = new JLabel(); jLabel4D .setBounds( new Rectangle(150, 445, 163, 19)); jLabel4D .setText( "Time run with MIL on" ); jLabel4D .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel4C = new JLabel(); jLabel4C .setBounds( new Rectangle(150, 405, 216, 19)); jLabel4C .setText( "Commanded throttle actuator" ); jLabel4C .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel4B = new JLabel(); jLabel4B .setBounds( new Rectangle(150, 365, 209, 19)); jLabel4B .setText( "Accelerator pedal position F" ); jLabel4B .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel4A = new JLabel(); jLabel4A .setBounds( new Rectangle(150, 325, 209, 19)); jLabel4A .setText( "Accelerator pedal position E" ); jLabel4A .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel49 = new JLabel(); jLabel49 .setBounds( new Rectangle(150, 285, 211, 19)); jLabel49 .setText( "Accelerator pedal position D" ); jLabel49 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel48 = new JLabel(); jLabel48 .setBounds( new Rectangle(150, 245, 194, 19)); jLabel48 .setText( "Absolute throttle position C" ); jLabel48 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel47 = new JLabel(); jLabel47 .setBounds( new Rectangle(150, 205, 194, 19)); jLabel47 .setText( "Absolute throttle position B" ); jLabel47 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel46 = new JLabel(); jLabel46 .setBounds( new Rectangle(150, 165, 182, 19)); jLabel46 .setText( "Ambient air temperature" ); jLabel46 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel45 = new JLabel(); jLabel45 .setBounds( new Rectangle(150, 125, 179, 19)); jLabel45 .setText( "Relative throttle position" ); jLabel45 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel44 = new JLabel(); jLabel44 .setBounds( new Rectangle(150, 85, 201, 19)); jLabel44 .setText( "Command equivalence ratio" ); jLabel44 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel43 = new JLabel(); jLabel43 .setBounds( new Rectangle(150, 45, 147, 19)); jLabel43 .setText( "Absolute load value" ); jLabel43 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jLabel42 = new JLabel();

Page 128: ProjecteOscar-memoria

128

jLabel42 .setBounds( new Rectangle(150, 5, 176, 19)); jLabel42 .setText( "Control module voltage" ); jLabel42 .setFont( new Font( "Dialog" , Font. PLAIN, 14)); jPanel41_60 = new JPanel(); jPanel41_60 .setLayout( null); jPanel41_60 .add(getJTextField42(), null); jPanel41_60 .add(getJTextField43(), null); jPanel41_60 .add(getJTextField44(), null); jPanel41_60 .add(getJTextField45(), null); jPanel41_60 .add(getJTextField46(), null); jPanel41_60 .add(getJTextField47(), null); jPanel41_60 .add(getJTextField48(), null); jPanel41_60 .add(getJTextField49(), null); jPanel41_60 .add(getJTextField4A(), null); jPanel41_60 .add(getJTextField4B(), null); jPanel41_60 .add(getJTextField4C(), null); jPanel41_60 .add(getJTextField4D(), null); jPanel41_60 .add(getJTextField4E(), null); jPanel41_60 .add( jLabel42 , null); jPanel41_60 .add( jLabel43 , null); jPanel41_60 .add( jLabel44 , null); jPanel41_60 .add( jLabel45 , null); jPanel41_60 .add( jLabel46 , null); jPanel41_60 .add( jLabel47 , null); jPanel41_60 .add( jLabel48 , null); jPanel41_60 .add( jLabel49 , null); jPanel41_60 .add( jLabel4A , null); jPanel41_60 .add( jLabel4B , null); jPanel41_60 .add( jLabel4C , null); jPanel41_60 .add( jLabel4D , null); jPanel41_60 .add( jLabel4E , null); jPanel41_60 .add(getJTextField51(), null); jPanel41_60 .add( jLabel51 , null); jPanel41_60 .add( jLabel52 , null); jPanel41_60 .add(getJTextField52(), null); return jPanel41_60 ;

public JTextField getJTextField04() if ( jTextField04 == null) jTextField04 = new JTextField(); jTextField04 .setBounds( new Rectangle(5, 5, 140, 40)); jTextField04 .setHorizontalAlignment(JTextField. CENTER); jTextField04 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField04 .setEditable( false); jTextField04 .setBackground(Color. white); return jTextField04 ; public JTextField getJTextField05() if ( jTextField05 == null) jTextField05 = new JTextField(); jTextField05 .setBounds( new Rectangle(5, 45, 140, 40)); jTextField05 .setHorizontalAlignment(JTextField. CENTER); jTextField05 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField05 .setEditable( false); jTextField05 .setBackground(Color. white); return jTextField05 ;

Page 129: ProjecteOscar-memoria

129

public JTextField getJTextField06() if ( jTextField06 == null) jTextField06 = new JTextField(); jTextField06 .setBounds( new Rectangle(5, 85, 140, 40)); jTextField06 .setHorizontalAlignment(JTextField. CENTER); jTextField06 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField06 .setEditable( false); jTextField06 .setBackground(Color. white); return jTextField06 ; public JTextField getJTextField07() if ( jTextField07 == null) jTextField07 = new JTextField(); jTextField07 .setBounds( new Rectangle(5, 125, 140, 40)); jTextField07 .setHorizontalAlignment(JTextField. CENTER); jTextField07 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField07 .setEditable( false); jTextField07 .setBackground(Color. white); return jTextField07 ; public JTextField getJTextField08() if ( jTextField08 == null) jTextField08 = new JTextField(); jTextField08 .setBounds( new Rectangle(5, 165, 140, 40)); jTextField08 .setHorizontalAlignment(JTextField. CENTER); jTextField08 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField08 .setEditable( false); jTextField08 .setBackground(Color. white); return jTextField08 ;

public JTextField getJTextField09() if ( jTextField09 == null) jTextField09 = new JTextField(); jTextField09 .setBounds( new Rectangle(5, 205, 140, 40)); jTextField09 .setHorizontalAlignment(JTextField. CENTER); jTextField09 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField09 .setEditable( false); jTextField09 .setBackground(Color. white); return jTextField09 ;

public JTextField getJTextField0A() if ( jTextField0A == null) jTextField0A = new JTextField(); jTextField0A .setBounds( new Rectangle(5, 245, 140, 40)); jTextField0A .setHorizontalAlignment(JTextField. CENTER); jTextField0A .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField0A .setEditable( false); jTextField0A .setBackground(Color. white); return jTextField0A ; public JTextField getJTextField0B() if ( jTextField0B == null) jTextField0B = new JTextField();

Page 130: ProjecteOscar-memoria

130

jTextField0B .setBounds( new Rectangle(5, 285, 140, 40)); jTextField0B .setHorizontalAlignment(JTextField. CENTER); jTextField0B .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField0B .setEditable( false); jTextField0B .setBackground(Color. white); return jTextField0B ; public JTextField getJTextField0C() if ( jTextField0C == null) jTextField0C = new JTextField(); jTextField0C .setBounds( new Rectangle(5, 325, 140, 40)); jTextField0C .setHorizontalAlignment(JTextField. CENTER); jTextField0C .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField0C .setEditable( false); jTextField0C .setBackground(Color. white); return jTextField0C ; public JTextField getJTextField0D() if ( jTextField0D == null) jTextField0D = new JTextField(); jTextField0D .setBounds( new Rectangle(5, 365, 140, 40)); jTextField0D .setHorizontalAlignment(JTextField. CENTER); jTextField0D .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField0D .setEditable( false); jTextField0D .setBackground(Color. white); return jTextField0D ; public JTextField getJTextField0E() if ( jTextField0E == null) jTextField0E = new JTextField(); jTextField0E .setBounds( new Rectangle(5, 405, 140, 40)); jTextField0E .setHorizontalAlignment(JTextField. CENTER); jTextField0E .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField0E .setEditable( false); jTextField0E .setBackground(Color. white); return jTextField0E ; public JTextField getJTextField0F() if ( jTextField0F == null) jTextField0F = new JTextField(); jTextField0F .setBounds( new Rectangle(5, 445, 140, 40)); jTextField0F .setHorizontalAlignment(JTextField. CENTER); jTextField0F .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField0F .setEditable( false); jTextField0F .setBackground(Color. white); return jTextField0F ; public JTextField getJTextField10() if ( jTextField10 == null) jTextField10 = new JTextField(); jTextField10 .setBounds( new Rectangle(380, 5, 140, 40)); jTextField10 .setHorizontalAlignment(JTextField. CENTER); jTextField10 .setFont( new Font( "Dialog" , Font. BOLD, 22));

Page 131: ProjecteOscar-memoria

131

jTextField10 .setEditable( false); jTextField10 .setBackground(Color. white); return jTextField10 ;

public JTextField getJTextField11() if ( jTextField11 == null) jTextField11 = new JTextField(); jTextField11 .setBounds( new Rectangle(380, 45, 140, 40)); jTextField11 .setHorizontalAlignment(JTextField. CENTER); jTextField11 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField11 .setEditable( false); jTextField11 .setBackground(Color. white); return jTextField11 ; public JTextField getJTextField12() if ( jTextField12 == null) jTextField12 = new JTextField(); jTextField12 .setBounds( new Rectangle(380, 85, 291, 53)); jTextField12 .setHorizontalAlignment(JTextField. CENTER); jTextField12 .setFont( new Font( "Dialog" , Font. PLAIN, 17)); jTextField12 .setEditable( false); jTextField12 .setBackground(Color. white); return jTextField12 ;

public JTextField getJTextField14() if ( jTextField14 == null) jTextField14 = new JTextField(); jTextField14 .setBounds( new Rectangle(380, 165, 140, 40)); jTextField14 .setHorizontalAlignment(JTextField. CENTER); jTextField14 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField14 .setEditable( false); jTextField14 .setBackground(Color. white); return jTextField14 ; public JTextField getJTextField15() if ( jTextField15 == null) jTextField15 = new JTextField(); jTextField15 .setBounds( new Rectangle(380, 205, 140, 40)); jTextField15 .setHorizontalAlignment(JTextField. CENTER); jTextField15 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField15 .setEditable( false); jTextField15 .setBackground(Color. white); return jTextField15 ; public JTextField getJTextField16() if ( jTextField16 == null) jTextField16 = new JTextField(); jTextField16 .setBounds( new Rectangle(380, 245, 140, 40)); jTextField16 .setHorizontalAlignment(JTextField. CENTER); jTextField16 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField16 .setEditable( false); jTextField16 .setBackground(Color. white);

Page 132: ProjecteOscar-memoria

132

return jTextField16 ; public JTextField getJTextField17() if ( jTextField17 == null) jTextField17 = new JTextField(); jTextField17 .setBounds( new Rectangle(380, 285, 140, 40)); jTextField17 .setHorizontalAlignment(JTextField. CENTER); jTextField17 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField17 .setEditable( false); jTextField17 .setBackground(Color. white); return jTextField17 ;

public JTextField getJTextField18() if ( jTextField18 == null) jTextField18 = new JTextField(); jTextField18 .setBounds( new Rectangle(380, 325, 140, 40)); jTextField18 .setHorizontalAlignment(JTextField. CENTER); jTextField18 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField18 .setEditable( false); jTextField18 .setBackground(Color. white); return jTextField18 ;

public JTextField getJTextField19() if ( jTextField19 == null) jTextField19 = new JTextField(); jTextField19 .setBounds( new Rectangle(380, 365, 140, 40)); jTextField19 .setHorizontalAlignment(JTextField. CENTER); jTextField19 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField19 .setEditable( false); jTextField19 .setBackground(Color. white); return jTextField19 ; public JTextField getJTextField1A() if ( jTextField1A == null) jTextField1A = new JTextField(); jTextField1A .setBounds( new Rectangle(380, 405, 140, 40)); jTextField1A .setHorizontalAlignment(JTextField. CENTER); jTextField1A .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField1A .setEditable( false); jTextField1A .setBackground(Color. white); return jTextField1A ; public JTextField getJTextField1B() if ( jTextField1B == null) jTextField1B = new JTextField(); jTextField1B .setBounds( new Rectangle(380, 445, 140, 40)); jTextField1B .setHorizontalAlignment(JTextField. CENTER); jTextField1B .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField1B .setEditable( false); jTextField1B .setBackground(Color. white); return jTextField1B ; public JTextField getJTextField1E()

Page 133: ProjecteOscar-memoria

133

if ( jTextField1E == null) jTextField1E = new JTextField(); jTextField1E .setBounds( new Rectangle(380, 485, 140, 40)); jTextField1E .setHorizontalAlignment(JTextField. CENTER); jTextField1E .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField1E .setEditable( false); jTextField1E .setBackground(Color. white); return jTextField1E ; public JTextField getJTextField1F() if ( jTextField1F == null) jTextField1F = new JTextField(); jTextField1F .setBounds( new Rectangle(380, 525, 140, 40)); jTextField1F .setHorizontalAlignment(JTextField. CENTER); jTextField1F .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField1F .setEditable( false); jTextField1F .setBackground(Color. white); return jTextField1F ; public JTextField getJTextField24() if ( jTextField24 == null) jTextField24 = new JTextField(); jTextField24 .setBounds( new Rectangle(5, 125, 140, 40)); jTextField24 .setHorizontalAlignment(JTextField. CENTER); jTextField24 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField24 .setEditable( false); jTextField24 .setBackground(Color. white); return jTextField24 ; public JTextField getJTextField25() if ( jTextField25 == null) jTextField25 = new JTextField(); jTextField25 .setBounds( new Rectangle(5, 165, 140, 40)); jTextField25 .setHorizontalAlignment(JTextField. CENTER); jTextField25 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField25 .setEditable( false); jTextField25 .setBackground(Color. white); return jTextField25 ; public JTextField getJTextField26() if ( jTextField26 == null) jTextField26 = new JTextField(); jTextField26 .setBounds( new Rectangle(5, 205, 140, 40)); jTextField26 .setHorizontalAlignment(JTextField. CENTER); jTextField26 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField26 .setEditable( false); jTextField26 .setBackground(Color. white); return jTextField26 ; public JTextField getJTextField27() if ( jTextField27 == null) jTextField27 = new JTextField(); jTextField27 .setBounds( new Rectangle(5, 245, 140, 40));

Page 134: ProjecteOscar-memoria

134

jTextField27 .setHorizontalAlignment(JTextField. CENTER); jTextField27 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField27 .setEditable( false); jTextField27 .setBackground(Color. white); return jTextField27 ; public JTextField getJTextField28() if ( jTextField28 == null) jTextField28 = new JTextField(); jTextField28 .setBounds( new Rectangle(5, 285, 140, 40)); jTextField28 .setHorizontalAlignment(JTextField. CENTER); jTextField28 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField28 .setEditable( false); jTextField28 .setBackground(Color. white); return jTextField28 ; public JTextField getJTextField29() if ( jTextField29 == null) jTextField29 = new JTextField(); jTextField29 .setBounds( new Rectangle(5, 325, 140, 40)); jTextField29 .setHorizontalAlignment(JTextField. CENTER); jTextField29 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField29 .setEditable( false); jTextField29 .setBackground(Color. white); return jTextField29 ; public JTextField getJTextField2A() if ( jTextField2A == null) jTextField2A = new JTextField(); jTextField2A .setBounds( new Rectangle(5, 365, 140, 40)); jTextField2A .setHorizontalAlignment(JTextField. CENTER); jTextField2A .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField2A .setEditable( false); jTextField2A .setBackground(Color. white); return jTextField2A ;

public JTextField getJTextField2B() if ( jTextField2B == null) jTextField2B = new JTextField(); jTextField2B .setBounds( new Rectangle(5, 405, 140, 40)); jTextField2B .setHorizontalAlignment(JTextField. CENTER); jTextField2B .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField2B .setEditable( false); jTextField2B .setBackground(Color. white); return jTextField2B ;

public JTextField getJTextField2C() if ( jTextField2C == null) jTextField2C = new JTextField(); jTextField2C .setBounds( new Rectangle(5, 445, 140, 40)); jTextField2C .setHorizontalAlignment(JTextField. CENTER); jTextField2C .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField2C .setEditable( false);

Page 135: ProjecteOscar-memoria

135

jTextField2C .setBackground(Color. white); return jTextField2C ; public JTextField getJTextField2D() if ( jTextField2D == null) jTextField2D = new JTextField(); jTextField2D .setBounds( new Rectangle(5, 485, 140, 40)); jTextField2D .setHorizontalAlignment(JTextField. CENTER); jTextField2D .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField2D .setEditable( false); jTextField2D .setBackground(Color. white); return jTextField2D ;

public JTextField getJTextField2E() if ( jTextField2E == null) jTextField2E = new JTextField(); jTextField2E .setBounds( new Rectangle(5, 525, 140, 40)); jTextField2E .setHorizontalAlignment(JTextField. CENTER); jTextField2E .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField2E .setEditable( false); jTextField2E .setBackground(Color. white); return jTextField2E ;

public JTextField getJTextField2F() if ( jTextField2F == null) jTextField2F = new JTextField(); jTextField2F .setBounds( new Rectangle(5, 565, 140, 40)); jTextField2F .setHorizontalAlignment(JTextField. CENTER); jTextField2F .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField2F .setEditable( false); jTextField2F .setBackground(Color. white); return jTextField2F ; public JTextField getJTextField33() if ( jTextField33 == null) jTextField33 = new JTextField(); jTextField33 .setBounds( new Rectangle(380, 85, 140, 40)); jTextField33 .setHorizontalAlignment(JTextField. CENTER); jTextField33 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField33 .setEditable( false); jTextField33 .setBackground(Color. white); return jTextField33 ;

public JTextField getJTextField31() if ( jTextField31 == null) jTextField31 = new JTextField(); jTextField31 .setBounds( new Rectangle(380, 5, 140, 40)); jTextField31 .setHorizontalAlignment(JTextField. CENTER); jTextField31 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField31 .setEditable( false); jTextField31 .setBackground(Color. white); return jTextField31 ;

Page 136: ProjecteOscar-memoria

136

public JTextField getJTextField32() if ( jTextField32 == null) jTextField32 = new JTextField(); jTextField32 .setBounds( new Rectangle(380, 45, 140, 40)); jTextField32 .setHorizontalAlignment(JTextField. CENTER); jTextField32 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField32 .setEditable( false); jTextField32 .setBackground(Color. white); return jTextField32 ; public JTextField getJTextField34() if ( jTextField34 == null) jTextField34 = new JTextField(); jTextField34 .setBounds( new Rectangle(380, 125, 140, 40)); jTextField34 .setHorizontalAlignment(JTextField. CENTER); jTextField34 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField34 .setEditable( false); jTextField34 .setBackground(Color. white); return jTextField34 ;

public JTextField getJTextField35() if ( jTextField35 == null) jTextField35 = new JTextField(); jTextField35 .setBounds( new Rectangle(380, 165, 140, 40)); jTextField35 .setHorizontalAlignment(JTextField. CENTER); jTextField35 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField35 .setEditable( false); jTextField35 .setBackground(Color. white); return jTextField35 ; public JTextField getJTextField36() if ( jTextField36 == null) jTextField36 = new JTextField(); jTextField36 .setBounds( new Rectangle(380, 205, 140, 40)); jTextField36 .setHorizontalAlignment(JTextField. CENTER); jTextField36 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField36 .setEditable( false); jTextField36 .setBackground(Color. white); return jTextField36 ; public JTextField getJTextField37() if ( jTextField37 == null) jTextField37 = new JTextField(); jTextField37 .setBounds( new Rectangle(380, 245, 140, 40)); jTextField37 .setHorizontalAlignment(JTextField. CENTER); jTextField37 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField37 .setEditable( false); jTextField37 .setBackground(Color. white); return jTextField37 ; public JTextField getJTextField38()

Page 137: ProjecteOscar-memoria

137

if ( jTextField38 == null) jTextField38 = new JTextField(); jTextField38 .setBounds( new Rectangle(380, 285, 140, 40)); jTextField38 .setHorizontalAlignment(JTextField. CENTER); jTextField38 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField38 .setEditable( false); jTextField38 .setBackground(Color. white); return jTextField38 ; public JTextField getJTextField39() if ( jTextField39 == null) jTextField39 = new JTextField(); jTextField39 .setBounds( new Rectangle(380, 325, 140, 40)); jTextField39 .setHorizontalAlignment(JTextField. CENTER); jTextField39 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField39 .setEditable( false); jTextField39 .setBackground(Color. white); return jTextField39 ; public JTextField getJTextField3A() if ( jTextField3A == null) jTextField3A = new JTextField(); jTextField3A .setBounds( new Rectangle(380, 365, 140, 40)); jTextField3A .setHorizontalAlignment(JTextField. CENTER); jTextField3A .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField3A .setEditable( false); jTextField3A .setBackground(Color. white); return jTextField3A ; public JTextField getJTextField3B() if ( jTextField3B == null) jTextField3B = new JTextField(); jTextField3B .setBounds( new Rectangle(380, 405, 140, 40)); jTextField3B .setHorizontalAlignment(JTextField. CENTER); jTextField3B .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField3B .setEditable( false); jTextField3B .setBackground(Color. white); return jTextField3B ;

public JTextField getJTextField3E() if ( jTextField3E == null) jTextField3E = new JTextField(); jTextField3E .setBounds( new Rectangle(380, 525, 140, 40)); jTextField3E .setHorizontalAlignment(JTextField. CENTER); jTextField3E .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField3E .setEditable( false); jTextField3E .setBackground(Color. white); return jTextField3E ;

public JTextField getJTextField3F() if ( jTextField3F == null) jTextField3F = new JTextField(); jTextField3F .setBounds( new Rectangle(380, 565, 140, 40));

Page 138: ProjecteOscar-memoria

138

jTextField3F .setHorizontalAlignment(JTextField. CENTER); jTextField3F .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField3F .setEditable( false); jTextField3F .setBackground(Color. white); return jTextField3F ;

public JTextField getJTextField21() if ( jTextField21 == null) jTextField21 = new JTextField(); jTextField21 .setBounds( new Rectangle(5, 5, 140, 40)); jTextField21 .setHorizontalAlignment(JTextField. CENTER); jTextField21 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField21 .setEditable( false); jTextField21 .setBackground(Color. white); return jTextField21 ; public JTextField getJTextField22() if ( jTextField22 == null) jTextField22 = new JTextField(); jTextField22 .setBounds( new Rectangle(5, 45, 140, 40)); jTextField22 .setHorizontalAlignment(JTextField. CENTER); jTextField22 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField22 .setEditable( false); jTextField22 .setBackground(Color. white); return jTextField22 ; public JTextField getJTextField23() if ( jTextField23 == null) jTextField23 = new JTextField(); jTextField23 .setBounds( new Rectangle(5, 85, 140, 40)); jTextField23 .setHorizontalAlignment(JTextField. CENTER); jTextField23 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField23 .setEditable( false); jTextField23 .setBackground(Color. white); return jTextField23 ;

public JTextField getJTextField3C() if ( jTextField3C == null) jTextField3C = new JTextField(); jTextField3C .setBounds( new Rectangle(380, 445, 140, 40)); jTextField3C .setHorizontalAlignment(JTextField. CENTER); jTextField3C .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField3C .setEditable( false); jTextField3C .setBackground(Color. white); return jTextField3C ;

public JTextField getJTextField3D() if ( jTextField3D == null) jTextField3D = new JTextField(); jTextField3D .setBounds( new Rectangle(380, 485, 140, 40)); jTextField3D .setHorizontalAlignment(JTextField. CENTER); jTextField3D .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField3D .setEditable( false);

Page 139: ProjecteOscar-memoria

139

jTextField3D .setBackground(Color. white); return jTextField3D ; public JButton getJButtonLeer() if ( jButtonLeer == null) jButtonLeer = new JButton(); jButtonLeer .setBounds( new Rectangle(6, 650, 130, 20)); jButtonLeer .setText( "Start reading" ); return jButtonLeer ; public JButton getJButtonDetener() if ( jButtonDetener == null) jButtonDetener = new JButton(); jButtonDetener .setBounds( new Rectangle(135, 650, 130, 20)); jButtonDetener .setText( "Stop" ); return jButtonDetener ;

public JTextField getJTextField42() if ( jTextField42 == null) jTextField42 = new JTextField(); jTextField42 .setBounds( new Rectangle(5, 5, 140, 40)); jTextField42 .setHorizontalAlignment(JTextField. CENTER); jTextField42 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField42 .setEditable( false); jTextField42 .setBackground(Color. white); return jTextField42 ;

public JTextField getJTextField43() if ( jTextField43 == null) jTextField43 = new JTextField(); jTextField43 .setBounds( new Rectangle(5, 45, 140, 40)); jTextField43 .setHorizontalAlignment(JTextField. CENTER); jTextField43 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField43 .setEditable( false); jTextField43 .setBackground(Color. white); return jTextField43 ; public JTextField getJTextField44() if ( jTextField44 == null) jTextField44 = new JTextField(); jTextField44 .setBounds( new Rectangle(5, 85, 140, 40)); jTextField44 .setHorizontalAlignment(JTextField. CENTER); jTextField44 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField44 .setEditable( false); jTextField44 .setBackground(Color. white); return jTextField44 ; public JTextField getJTextField45() if ( jTextField45 == null)

Page 140: ProjecteOscar-memoria

140

jTextField45 = new JTextField(); jTextField45 .setBounds( new Rectangle(5, 125, 140, 40)); jTextField45 .setHorizontalAlignment(JTextField. CENTER); jTextField45 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField45 .setEditable( false); jTextField45 .setBackground(Color. white); return jTextField45 ;

public JTextField getJTextField46() if ( jTextField46 == null) jTextField46 = new JTextField(); jTextField46 .setBounds( new Rectangle(5, 165, 140, 40)); jTextField46 .setHorizontalAlignment(JTextField. CENTER); jTextField46 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField46 .setEditable( false); jTextField46 .setBackground(Color. white); return jTextField46 ; public JTextField getJTextField47() if ( jTextField47 == null) jTextField47 = new JTextField(); jTextField47 .setBounds( new Rectangle(5, 205, 140, 40)); jTextField47 .setHorizontalAlignment(JTextField. CENTER); jTextField47 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField47 .setEditable( false); jTextField47 .setBackground(Color. white); return jTextField47 ; public JTextField getJTextField48() if ( jTextField48 == null) jTextField48 = new JTextField(); jTextField48 .setBounds( new Rectangle(5, 245, 140, 40)); jTextField48 .setHorizontalAlignment(JTextField. CENTER); jTextField48 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField48 .setEditable( false); jTextField48 .setBackground(Color. white); return jTextField48 ; public JTextField getJTextField49() if ( jTextField49 == null) jTextField49 = new JTextField(); jTextField49 .setBounds( new Rectangle(5, 285, 140, 40)); jTextField49 .setHorizontalAlignment(JTextField. CENTER); jTextField49 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField49 .setEditable( false); jTextField49 .setBackground(Color. white); return jTextField49 ; public JTextField getJTextField4A() if ( jTextField4A == null) jTextField4A = new JTextField(); jTextField4A .setBounds( new Rectangle(5, 325, 140, 40)); jTextField4A .setHorizontalAlignment(JTextField. CENTER);

Page 141: ProjecteOscar-memoria

141

jTextField4A .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField4A .setEditable( false); jTextField4A .setBackground(Color. white); return jTextField4A ; public JTextField getJTextField4B() if ( jTextField4B == null) jTextField4B = new JTextField(); jTextField4B .setBounds( new Rectangle(5, 365, 140, 40)); jTextField4B .setHorizontalAlignment(JTextField. CENTER); jTextField4B .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField4B .setEditable( false); jTextField4B .setBackground(Color. white); return jTextField4B ; public JTextField getJTextField4C() if ( jTextField4C == null) jTextField4C = new JTextField(); jTextField4C .setBounds( new Rectangle(5, 405, 140, 40)); jTextField4C .setHorizontalAlignment(JTextField. CENTER); jTextField4C .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField4C .setEditable( false); jTextField4C .setBackground(Color. white); return jTextField4C ; public JTextField getJTextField4D() if ( jTextField4D == null) jTextField4D = new JTextField(); jTextField4D .setBounds( new Rectangle(5, 445, 140, 40)); jTextField4D .setHorizontalAlignment(JTextField. CENTER); jTextField4D .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField4D .setEditable( false); jTextField4D .setBackground(Color. white); return jTextField4D ; public JTextField getJTextField4E() if ( jTextField4E == null) jTextField4E = new JTextField(); jTextField4E .setBounds( new Rectangle(5, 485, 140, 40)); jTextField4E .setHorizontalAlignment(JTextField. CENTER); jTextField4E .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField4E .setEditable( false); jTextField4E .setBackground(Color. white); return jTextField4E ; public JTextField getJTextField51() if ( jTextField51 == null) jTextField51 = new JTextField(); jTextField51 .setBounds( new Rectangle(380, 25, 336, 59)); jTextField51 .setHorizontalAlignment(JTextField. CENTER); jTextField51 .setFont( new Font( "Dialog" , Font. PLAIN, 17)); jTextField51 .setEditable( false); jTextField51 .setBackground(Color. white);

Page 142: ProjecteOscar-memoria

142

return jTextField51 ; public JTextField getJTextField52() if ( jTextField52 == null) jTextField52 = new JTextField(); jTextField52 .setBounds( new Rectangle(380, 85, 140, 40)); jTextField52 .setHorizontalAlignment(JTextField. CENTER); jTextField52 .setFont( new Font( "Dialog" , Font. BOLD, 22)); jTextField52 .setEditable( false); jTextField52 .setBackground(Color. white); return jTextField52 ;

public JTextField getJTextField1C() if ( jTextField1C == null) jTextField1C = new JTextField(); jTextField1C .setBounds( new Rectangle(5, 525, 300, 40)); jTextField1C .setFont( new Font( "Dialog" , Font. PLAIN, 17)); jTextField1C .setEditable( false); jTextField1C .setBackground(Color. white); return jTextField1C ;

Clase VistaPrincipal:

package Presentacion; import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import java.awt.Rectangle; import javax.swing.JButton; import javax.swing.JTextArea; import java.awt.Point; import javax.swing.JScrollPane; import javax.swing.JTextField; public class VistaPrincipal extends JFrame private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JMenuBar jJMenuBar = null; private JMenu jMenuInicio = null; private JMenuItem jMenuItemErrores = null; private JMenuItem jMenuItemLectura = null; private JPanel jPanel = null; private JButton jButtonConectar = null;

Page 143: ProjecteOscar-memoria

143

private JButton jButtonDesconectar = null; private JTextArea jTextArea = null; private JMenu jMenuOpciones = null; private JMenu jMenuAyuda = null; private JMenuItem jMenuItemPSerie = null; private JMenuItem jMenuItemProtocolo = null; private JScrollPane jScrollPane = null; private JButton jButtonEnvioManual = null; private JTextField jTextFieldEnvioManual = null; private JMenuItem jMenuItemPresentacion = null; private JMenuItem jMenuItemAbout = null; private JMenuItem jMenuItemExit = null;

public VistaPrincipal() super(); this.setLocation( new Point(100, 25)); initialize();

public void initialize() this.setSize(1050, 734); this.setContentPane(getJContentPane()); this.setJMenuBar(getJJMenuBar()); this.setTitle( "VisualOBD" ); this.setVisible( true); public JPanel getJContentPane() if ( jContentPane == null) jContentPane = new JPanel(); jContentPane .setLayout( null); jContentPane .add(getJPanel(), null); return jContentPane ;

private JMenuBar getJJMenuBar() if ( jJMenuBar == null) jJMenuBar = new JMenuBar(); jJMenuBar .add(getJMenuInicio()); jJMenuBar .add(getJMenuOpciones()); jJMenuBar .add(getJMenuAyuda()); return jJMenuBar ; private JMenu getJMenuInicio() if ( jMenuInicio == null) jMenuInicio = new JMenu(); jMenuInicio .setText( " Start " ); jMenuInicio .add(getJMenuItemPresentacion()); jMenuInicio .add(getJMenuItemErrores());

Page 144: ProjecteOscar-memoria

144

jMenuInicio .add(getJMenuItemLectura()); jMenuInicio .add(getJMenuItemExit()); return jMenuInicio ;

public JMenuItem getJMenuItemErrores() if ( jMenuItemErrores == null) jMenuItemErrores = new JMenuItem(); jMenuItemErrores .setText( "Reading errors" ); return jMenuItemErrores ;

public JMenuItem getJMenuItemLectura() if ( jMenuItemLectura == null) jMenuItemLectura = new JMenuItem(); jMenuItemLectura .setText( "Real-time measurements" ); return jMenuItemLectura ;

private JPanel getJPanel() if ( jPanel == null) jPanel = new JPanel(); jPanel .setLayout( null); jPanel .setBounds( new Rectangle(795, 2, 250, 675)); jPanel .add(getJButtonConectar(), null); jPanel .add(getJButtonDesconectar(), null); jPanel .add(getJScrollPane(), null); jPanel .add(getJButtonEnvioManual(), null); jPanel .add(getJTextFieldEnvioManual(), null); return jPanel ; public JButton getJButtonConectar() if ( jButtonConectar == null) jButtonConectar = new JButton(); jButtonConectar .setBounds( new Rectangle(5, 647, 115, 20)); jButtonConectar .setText( "Connect" ); return jButtonConectar ; public JButton getJButtonDesconectar() if ( jButtonDesconectar == null) jButtonDesconectar = new JButton(); jButtonDesconectar .setBounds( new Rectangle(120, 647, 119, 20)); jButtonDesconectar .setText( "Disconnect" ); return jButtonDesconectar ;

public JTextArea getJTextArea() if ( jTextArea == null) jTextArea = new JTextArea(); jTextArea .setEditable( false); return jTextArea ;

Page 145: ProjecteOscar-memoria

145

private JMenu getJMenuOpciones() if ( jMenuOpciones == null) jMenuOpciones = new JMenu(); jMenuOpciones .setText( " Options " ); jMenuOpciones .add(getJMenuItemPSerie()); jMenuOpciones .add(getJMenuItemProtocolo()); return jMenuOpciones ; private JMenu getJMenuAyuda() if ( jMenuAyuda == null) jMenuAyuda = new JMenu(); jMenuAyuda .setText( " Help " ); jMenuAyuda .add(getJMenuItemAbout()); return jMenuAyuda ;

public JMenuItem getJMenuItemPSerie() if ( jMenuItemPSerie == null) jMenuItemPSerie = new JMenuItem(); jMenuItemPSerie .setText( "Serial Port configuration" ); return jMenuItemPSerie ; public JMenuItem getJMenuItemProtocolo() if ( jMenuItemProtocolo == null) jMenuItemProtocolo = new JMenuItem(); jMenuItemProtocolo .setText( "Communication protocol configuration" ); return jMenuItemProtocolo ;

private JScrollPane getJScrollPane() if ( jScrollPane == null) jScrollPane = new JScrollPane(getJTextArea(),JScrollPane. VERTICAL_SCROLLBAR_ALWAYS,JScrollPane. HORIZONTAL_SCROLLBAR_ALWAYS); jScrollPane .setBounds( new Rectangle(5, 26, 235, 616)); jScrollPane .setViewportView(getJTextArea()); jScrollPane .setWheelScrollingEnabled( true); return jScrollPane ; public JButton getJButtonEnvioManual() if ( jButtonEnvioManual == null) jButtonEnvioManual = new JButton(); jButtonEnvioManual .setBounds( new Rectangle(163, 5, 77, 19)); jButtonEnvioManual .setText( "Send" ); return jButtonEnvioManual ;

public JTextField getJTextFieldEnvioManual() if ( jTextFieldEnvioManual == null) jTextFieldEnvioManual = new JTextField(); jTextFieldEnvioManual .setBounds( new Rectangle(5, 5, 159, 20));

Page 146: ProjecteOscar-memoria

146

return jTextFieldEnvioManual ;

public JMenuItem getJMenuItemPresentacion() if ( jMenuItemPresentacion == null) jMenuItemPresentacion = new JMenuItem(); jMenuItemPresentacion .setText( "Initial presentation" ); return jMenuItemPresentacion ; public JMenuItem getJMenuItemAbout() if ( jMenuItemAbout == null) jMenuItemAbout = new JMenuItem(); jMenuItemAbout .setText( "About VisualOBD" ); return jMenuItemAbout ; public JMenuItem getJMenuItemExit() if ( jMenuItemExit == null) jMenuItemExit = new JMenuItem(); jMenuItemExit .setText( "Exit" ); return jMenuItemExit ;

Clase VistaProtocolo:

package Presentacion; import java.awt.Dimension; import javax.swing.ButtonGroup; import javax.swing.JPanel; import javax.swing.JRadioButton; import java.awt.Rectangle; import javax.swing.JLabel; import java.awt.Font; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JButton; public class VistaProtocolo extends JPanel private static final long serialVersionUID = 1L; private JRadioButton jRadioButtonAutomatico = null; private JRadioButton jRadioButtonPWM = null; private JRadioButton jRadioButtonVPW = null; private JRadioButton jRadioButtonISO = null; private JRadioButton jRadioButtonKWP1 = null; private JRadioButton jRadioButtonKWP2 = null; private JRadioButton jRadioButtonCAN1 = null; private JRadioButton jRadioButtonCAN2 = null; private JRadioButton jRadioButtonCAN3 = null; private JRadioButton jRadioButtonCAN4 = null; private ButtonGroup grupoBotones ; private JLabel jLabelProtocolo = null; private JCheckBox jCheckBoxIntroHead = null;

Page 147: ProjecteOscar-memoria

147

private JComboBox jComboBoxPrio1 = null; private JComboBox jComboBoxPrio2 = null; private JComboBox jComboBoxRec1 = null; private JComboBox jComboBoxRec2 = null; private JComboBox jComboBoxTran1 = null; private JComboBox jComboBoxTran2 = null; private JLabel jLabelPrio = null; private JLabel jLabelRec = null; private JLabel jLabelTran = null; private JButton jButtonAplByHead = null; private String [] hexa = "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "A" , "B" , "C" , "D" , "E" , "F" ; public VistaProtocolo() super(); initialize(); private void initialize() jLabelTran = new JLabel(); jLabelTran .setBounds( new Rectangle(690, 120, 86, 16)); jLabelTran .setFont( new Font( "Dialog" , Font. PLAIN, 12)); jLabelTran .setText( "Tool address" ); jLabelRec = new JLabel(); jLabelRec .setBounds( new Rectangle(575, 120, 91, 16)); jLabelRec .setFont( new Font( "Dialog" , Font. PLAIN, 12)); jLabelRec .setText( "ECU address" ); jLabelPrio = new JLabel(); jLabelPrio .setBounds( new Rectangle(445, 120, 53, 16)); jLabelPrio .setFont( new Font( "Dialog" , Font. PLAIN, 12)); jLabelPrio .setText( "Priority" ); jLabelProtocolo = new JLabel(); jLabelProtocolo .setBounds( new Rectangle(10, 10, 375, 28)); jLabelProtocolo .setFont( new Font( "Dialog" , Font. BOLD, 18)); jLabelProtocolo .setText( "Selecting the communication protocol" ); this.setSize( new Dimension(775, 712)); this.setLayout( null); this.add(getJRadioButtonAutomatico(), null); this.add(getJRadioButtonPWM(), null); this.add(getJRadioButtonVPW(), null); this.add(getJRadioButtonISO(), null); this.add(getJRadioButtonKWP1(), null); this.add(getJRadioButtonKWP2(), null); this.add(getJRadioButtonCAN1(), null); this.add(getJRadioButtonCAN2(), null); this.add(getJRadioButtonCAN3(), null); this.add(getJRadioButtonCAN4(), null); this.add( jLabelProtocolo , null); this.add(getJCheckBoxIntroHead(), null); this.add(getJComboBoxPrio1(), null); this.add(getJComboBoxPrio2(), null); this.add(getJComboBoxRec1(), null); this.add(getJComboBoxRec2(), null); this.add(getJComboBoxTran1(), null); this.add(getJComboBoxTran2(), null); this.add( jLabelPrio , null); this.add( jLabelRec , null); this.add( jLabelTran , null); this.add(getJButtonAplByHead(), null); grupoBotones = new ButtonGroup(); grupoBotones .add(getJRadioButtonAutomatico()); grupoBotones .add(getJRadioButtonPWM()); grupoBotones .add(getJRadioButtonVPW()); grupoBotones .add(getJRadioButtonISO());

Page 148: ProjecteOscar-memoria

148

grupoBotones .add(getJRadioButtonKWP1()); grupoBotones .add(getJRadioButtonKWP2()); grupoBotones .add(getJRadioButtonCAN1()); grupoBotones .add(getJRadioButtonCAN2()); grupoBotones .add(getJRadioButtonCAN3()); grupoBotones .add(getJRadioButtonCAN4()); getJRadioButtonAutomatico().setSelected( true); public JRadioButton getJRadioButtonAutomatico() if ( jRadioButtonAutomatico == null) jRadioButtonAutomatico = new JRadioButton(); jRadioButtonAutomatico .setBounds( new Rectangle(10, 70, 328, 21)); jRadioButtonAutomatico .setText( "Automatic detection of communication protocol" ); return jRadioButtonAutomatico ; public JRadioButton getJRadioButtonPWM() if ( jRadioButtonPWM == null) jRadioButtonPWM = new JRadioButton(); jRadioButtonPWM .setBounds( new Rectangle(10, 120, 219, 21)); jRadioButtonPWM .setText( "SAE J1850 PWM (41.6 kBit/s)" ); return jRadioButtonPWM ; public JRadioButton getJRadioButtonVPW() if ( jRadioButtonVPW == null) jRadioButtonVPW = new JRadioButton(); jRadioButtonVPW .setBounds( new Rectangle(10, 170, 219, 21)); jRadioButtonVPW .setText( "SAE J1850 VPW (10.4 kBit/s)" ); return jRadioButtonVPW ; public JRadioButton getJRadioButtonISO() if ( jRadioButtonISO == null) jRadioButtonISO = new JRadioButton(); jRadioButtonISO .setBounds( new Rectangle(10, 220, 114, 21)); jRadioButtonISO .setText( "ISO 9141-2" ); return jRadioButtonISO ; public JRadioButton getJRadioButtonKWP1() if ( jRadioButtonKWP1 == null) jRadioButtonKWP1 = new JRadioButton(); jRadioButtonKWP1 .setBounds( new Rectangle(10, 270, 256, 21)); jRadioButtonKWP1 .setText( "ISO 14230-4 KWP2000 (5-baud init)" ); return jRadioButtonKWP1 ; public JRadioButton getJRadioButtonKWP2() if ( jRadioButtonKWP2 == null) jRadioButtonKWP2 = new JRadioButton(); jRadioButtonKWP2 .setBounds( new Rectangle(10, 320, 243, 21)); jRadioButtonKWP2 .setText( "ISO 14230-4 KWP2000 (fast init)" ); return jRadioButtonKWP2 ;

Page 149: ProjecteOscar-memoria

149

public JRadioButton getJRadioButtonCAN1() if ( jRadioButtonCAN1 == null) jRadioButtonCAN1 = new JRadioButton(); jRadioButtonCAN1 .setBounds( new Rectangle(10, 370, 300, 21)); jRadioButtonCAN1 .setText( "ISO 15765-4 CAN (11-bit ID, 500 kBit/s)" ); return jRadioButtonCAN1 ; public JRadioButton getJRadioButtonCAN2() if ( jRadioButtonCAN2 == null) jRadioButtonCAN2 = new JRadioButton(); jRadioButtonCAN2 .setBounds( new Rectangle(10, 420, 300, 21)); jRadioButtonCAN2 .setText( "ISO 15765-4 CAN (29-bit ID, 500 kBit/s)" ); return jRadioButtonCAN2 ;

public JRadioButton getJRadioButtonCAN3() if ( jRadioButtonCAN3 == null) jRadioButtonCAN3 = new JRadioButton(); jRadioButtonCAN3 .setBounds( new Rectangle(10, 470, 300, 21)); jRadioButtonCAN3 .setText( "ISO 15765-4 CAN (11-bit ID, 250 kBit/s)" ); return jRadioButtonCAN3 ;

public JRadioButton getJRadioButtonCAN4() if ( jRadioButtonCAN4 == null) jRadioButtonCAN4 = new JRadioButton(); jRadioButtonCAN4 .setBounds( new Rectangle(10, 520, 300, 21)); jRadioButtonCAN4 .setText( "ISO 15765-4 CAN (29-bit ID, 250 kBit/s)" ); return jRadioButtonCAN4 ;

public JCheckBox getJCheckBoxIntroHead() if ( jCheckBoxIntroHead == null) jCheckBoxIntroHead = new JCheckBox(); jCheckBoxIntroHead .setBounds( new Rectangle(425, 70, 254, 21)); jCheckBoxIntroHead .setFont( new Font( "Dialog" , Font. BOLD, 14)); jCheckBoxIntroHead .setText( "Enter specific header bytes" ); return jCheckBoxIntroHead ; public JComboBox getJComboBoxPrio1() if ( jComboBoxPrio1 == null) jComboBoxPrio1 = new JComboBox( hexa ); jComboBoxPrio1 .setBounds( new Rectangle(445, 135, 40, 20)); return jComboBoxPrio1 ; public JComboBox getJComboBoxPrio2() if ( jComboBoxPrio2 == null) jComboBoxPrio2 = new JComboBox( hexa ); jComboBoxPrio2 .setBounds( new Rectangle(484, 135, 40, 20)); return jComboBoxPrio2 ;

public JComboBox getJComboBoxRec1()

Page 150: ProjecteOscar-memoria

150

if ( jComboBoxRec1 == null) jComboBoxRec1 = new JComboBox( hexa ); jComboBoxRec1 .setBounds( new Rectangle(575, 135, 40, 20)); return jComboBoxRec1 ; public JComboBox getJComboBoxRec2() if ( jComboBoxRec2 == null) jComboBoxRec2 = new JComboBox( hexa ); jComboBoxRec2 .setBounds( new Rectangle(614, 135, 40, 20)); return jComboBoxRec2 ; public JComboBox getJComboBoxTran1() if ( jComboBoxTran1 == null) jComboBoxTran1 = new JComboBox( hexa ); jComboBoxTran1 .setBounds( new Rectangle(690, 135, 40, 20)); return jComboBoxTran1 ;

public JComboBox getJComboBoxTran2() if ( jComboBoxTran2 == null) jComboBoxTran2 = new JComboBox( hexa ); jComboBoxTran2 .setBounds( new Rectangle(729, 135, 40, 20)); return jComboBoxTran2 ; public JButton getJButtonAplByHead() if ( jButtonAplByHead == null) jButtonAplByHead = new JButton(); jButtonAplByHead .setBounds( new Rectangle(445, 180, 81, 18)); jButtonAplByHead .setText( "Apply" ); return jButtonAplByHead ;