Sie sind auf Seite 1von 150

DISEO Y REALIZACIN DE UN SISTEMA

ON BOARD DIAGNOSTICS (OBD-II)

ALUMNO: OSCAR RAYO MANSILLA


DIRECTOR: JORDI SELLARS GONZLEZ

4 DE JUNIO DE 2009
2
NDICE
1. Introduccin 5

1.1. Justificacin del proyecto5

1.2. Antecedentes..6

1.3. Objetivos..10

1.4. Alcance del proyecto11

1.5. Descripcin general del proyecto12

1.5.1. Descripcin bsica del hardware..12

1.5.2. Descripcin bsica del software...13

2. Diseos realizados 14

2.1. Metodologa utilizada14

2.2. Recursos utilizados..16

2.3. Descripcin del diseo del modem interface.21

2.4. Descripcin del diseo del programador JDM2......25

2.5. Modificaciones del diseo del modem..29

2.6. Diseo de la aplicacin de prueba en C++37

2.7. Diseo de la aplicacin de prueba en JAVA.40

2.8. Diseo de la aplicacin grfica diseada en JAVA.....46

3
3. Resultados 52

3.1. mbito de utilizacin.52

3.2. Validacin de los diseos.52

3.3. Descripcin del funcionamiento.54

3.4. Aplicaciones del proyecto66

4. Comentarios finales 67

4.1. Plan de trabajo67

4.2. Lista de materiales68

4.3. Presupuesto..70

4.4. Objetivos logrados71

4.5. Conclusiones.71

4.6. Mejoras futuras..72

5. Bibliografa 73

6. Anexo 74

4
1. Introduccin
1.1. Justificacin del proyecto
La motivacin principal de este proyecto es llegar a poder disear un sistema
con el que poder diagnosticar las posibles averas de cualquier vehculo sin
tener que recurrir a los costosos servicios oficiales.

Normalmente cuando se nos avera el coche siempre tenemos que acabar


recurriendo a los talleres de reparacin de los cuales dispone el fabricante de
nuestro vehculo, y aunque desconocemos cuales son los medios de los que
disponen para diagnosticar la avera, si sabemos que existe un herramienta que
conectndola al vehculo averigua el problema al instante. Esto se debe a que
estas marcas tan famosas equipan nuestros coches con sistemas electrnicos
capaces de gestionar toda la mecnica y electricidad de que dispone, sin ms
ayuda que la de un modulo electrnico.

En realidad estos mdulos no son ms que una pequea 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 aos estn
obligados a implementar un estndar de autodiagnstico llamado OBD-II, que
se hizo pblico a consecuencia de las grandes emisiones contaminantes a las
que estamos expuestos, implantando as un mecanismo de control de estas.

Estos mdulos 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 estn estafando, cosa que lamentablemente a veces pasa.

5
1.2. Antecedentes
OBD (On Board Diagnostics) es un sistema de diagnstico a bordo en vehculos
(coches y camiones). Actualmente se emplea OBD-II (Estados Unidos), EOBD
(Europa), y JOBD (Japn) estndar que aportan un control casi completo del
motor y otros dispositivos del vehculo. OBD II es la abreviatura de On Board
Diagnostics (Diagnstico de Abordo) II, la segunda generacin de los
requerimientos del equipamiento autodiagnosticable de abordo de los Estados
Unidos de Amrica. Las caractersticas de autodiagnstico de a bordo estn
incorporadas en el hardware y el software de la computadora de abordo de un
vehculo para monitorear prcticamente todos los componentes que pueden
afectar las emisiones. Cada componente es monitoreado por una rutina de
diagnstico para verificar si est funcionando perfectamente. Si se detecta un
problema o una falla, el sistema de OBD II ilumina una lmpara de advertencia
en el cuadro de instrumentos para avisarle al conductor.

La lmpara de advertencia normalmente lleva la inscripcin "Check Engine" o


"Service Engine Soon". El sistema tambin guarda informaciones importantes
sobre la falla detectada para que un mecnico pueda encontrar y resolver el
problema. En los Estados Unidos de Amrica, todos los vehculos 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 vehculos de pasajeros y camiones
de diesel a partir de 1997, en Europa a partir del ao 2001 se obliga implantar el
estndar EOBD. Adems, un pequeo nmero de vehculos de gas fueron
equipados con sistemas de OBD II.

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

OBD I fue la primera regulacin de OBD que obligaba a los productores a


instalar un sistema de monitoreo de algunos de los componentes controladores
de emisiones en automviles. Obligatorios en todos los vehculos 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 especfico de emisiones.

Y adems, qu es EOBD?

EOBD es la abreviatura de European On Board Diagnostics (Diagnstico de a


Bordo Europeo), la variacin europea de OBD II. Una de las diferencias es que
no se monitorean las evaporaciones del depsito. Sin embargo, EOBD es un
sistema mucho ms sofisticado que OBD II ya que usa "mapas" de las entradas a

6
los sensores expectadas basados en las condiciones de operacin del motor, y
los componentes se adaptan al sistema calibrndose empricamente. Esto
significa que los repuestos necesitan ser de alta calidad y especficos para el
vehculo y modelo.

Todos los estndares antes mencionados implementan varios modos de trabajo,


es decir, segn la parte de informacin a la que queramos acceder necesitamos
utilizar un modo diferente, dentro de cada uno de ellos podemos usar un
abanico de parmetros muy amplio.
Los modos de trabajo ms extendidos son los siguientes:

 Modo 01: Se utiliza para determinar qu informacin del modulo


electrnico (ECU) est a disposicin de la herramienta de exploracin.

 Modo 02: Muestra los llamados en este contexto Freeze Frame Data, es
decir, capturas puntuales de informacin que ha ido almacenado la ECU.

 Modo 03: Lista los posibles fallos producidos en la mecnica mediante


cdigos de error identificativos (DTC).

 Modo 04: Se utiliza para borrar los cdigos 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 autnoma 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
mnimo, mximo 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 tcnicos despus de una
reparacin del vehculo, y despus de borrar la informacin de
diagnstico para ver los resultados de las pruebas despus de un solo
ciclo de conduccin, determinando si la reparacin ha solucionado el
problema.
Slo 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 ms de 60 PIDs diferentes, no es poco el
trabajo a desarrollar.

7
Actualmente ya existen muchas herramientas y software disponible para poder
llevar a cabo la inspeccin de un vehculo 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 autnoma, 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 pequea cantidad de
dinero:

8
Tambin 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 cdigo
fuente con el que fue diseado:

Estos programas estn diseados para trabajar junto con el microcontrolador


ELM327, es decir, necesitan de este elemento intermedio entre el PC y el
vehculo. Existen en el mercado muchos modelos de interface disponibles en el
mercado, pero todas se basan en este micro. A continuacin podemos ver
algunos ejemplos:

Interface ELM327

9
Interface ELM327 Interface ELM327 con Bluetooth

En las imgenes vemos que los modelos tienen diferentes formas y diferentes
mtodos de conexin, ya que en uno de los casos se realiza por bluetooth,
pero su funcionamiento respecto al estndar OBD-II es idntico.

1.3. Objetivos
Este proyecto abarca una pequea parte del complejo campo de la
autodiagnosis en la automocin, 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 estndar OBD-II, aun siendo de libre acceso,
comprende modos de trabajo de los cuales no se tiene informacin en este
proyecto. Mucha de la documentacin que engloba al OBD-II est disponible
previo pago a las respectivas empresas que lo han diseado y estandarizado,
como es el caso de la Sociedad Americana de Ingenieros (SAE) o la Organizacin
Internacional para la Estandarizacin (ISO). Aun no disponiendo de toda la
informacin deseada los objetivos de este proyecto son bastante ambiciosos y
se pueden listar como sigue:

 Conseguir una comunicacin estable con cualquier centralita electrnica


(ECU) de cualquier vehculo equipado con OBD-II.

 Conseguir desarrollar una aplicacin portable a cualquier sistema


operativo y plataforma utilizando lenguaje JAVA y la estructura de
programacin por capas.

10
 Realizar mejoras en el hardware ya existente en el mercado a partir del
cual se construir nuestra interface.

 Demostrar que con la informacin disponible en la red, es posible


acceder a los sistemas de control que implementan los fabricantes de
automviles en sus vehculos.

1.4. Alcance del proyecto


El alcance de este proyecto incluye la creacin de un sistema que implementa
una parte de las grandes posibilidades que ofrece el OBD-II, pudindose usar
como una herramienta orientativa a la hora de diagnosticar una posible avera.

Este sistema utiliza por un lado un modem interface que adecua las seales
procedentes de la centralita electrnica que se encuentra en el vehculo (ECU), a
las seales que necesita un puerto USB de cualquier ordenador. A partir de aqu,
un software de control gestionara toda la informacin recibida. Muchos de los
mtodos de diagnostico existentes utilizan este planteamiento pero ninguno de
ellos, por lo menos oficialmente, utiliza una aplicacin desarrollada en JAVA
que, por lo tanto, permita ejecutarse en la mayora de los sistemas operativos
existentes, incluyendo el famoso Linux y adems en diferentes tipos de
plataformas.

Para desarrollar el hardware se utilizaran diseos de interfaces ya existentes a


partir de los cuales se crear la que se utilizara en este proyecto, es decir, se
recapitularan los esquemas elctricos de los que se dispongan y sobre el PCB
elegido se aadirn las posibles mejoras que pudieran aportar otros diseos.
Esta parte del trabajo tambin conlleva la construccin 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 ms importante,


ya que para conseguir disear la aplicacin de control sobre el modem
interface, se necesitan realizar los primeros programas de prueba que servirn
para constatar las bases del funcionamiento de la ltima y definitiva aplicacin
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 fcilmente comprensible dejando as todo el proceso de clculo en
segundo plano.

11
1.5. Descripcin 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 electrnica que
gestiona cualquiera de los vehculos dotados con el estndar OBD-II, y para
llevarlo acabo ha sido necesario trabajar sobre diferentes aspectos que estn
involucrados en el proceso de comunicacin. 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 ms que un


modem interface que hace de intrprete entre la centralita electrnica
del automvil (ECU), y el puerto USB de un ordenador personal.

 La parte que engloba el software, que se refiere a la aplicacin 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 Descripcin bsica del hardware (Modem interface)


Para disear el modem interface se recurri a diseos ya existentes y de libre
disposicin en la red, con el fin de conseguir construir una interface que
aportase las mejoras que de forma individual cada diseo implementa.
Esta interface contiene como elemento principal un microcontrolador
(PIC18F2550) que es el encargado de gestionar la comunicacin entre los dos
perifricos en cuestin, es decir, recoge la informacin que obtiene del puerto
USB y la interpreta segn el protocolo en que se est comunicando con la ECU.
Esto se debe a que el estndar OBD-II implementa 4 posibles protocolos en su
capa fsica, SAEJ1850PWM, ISO 9141/14230, J1850 VPW, ISO 15765 (CAN).
Para que el micro pueda realizar estas funciones se dispone adems de un
firmware que implementa las capacidades antes descritas, lo que lleva por tanto
a realizar su grabacin en el micro, y adems a la construccin de un
programador con el cual realizar este proceso.
Otro aspecto importante a resaltar es la necesidad de construir un cable
especfico para realizar la conexin entre la ECU y la interface durante las
primeras pruebas, ya que las centralitas electrnicas disponen de un conector
exclusivo para este uso, y por tanto es muy difcil de encontrar en el mercado
material compatible.

12
1.5.2 Descripcin bsica del software (Interface Visual)
Para realizar la aplicacin que gestionar el modem y todos los datos que sern
enviados y recibidos a travs 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 cul es el mecanismo que siguen
otras aplicaciones que ya implementan este mecanismo, y para poder hacerlo
existe una aplicacin, mencionada anteriormente (ScanTool), que ofrece el
cdigo fuente mediante lenguaje C++. A travs de este cdigo es posible extraer
las rutinas bsicas con las que se realiza la comunicacin con el micro y la ECU,
esto permite que nosotros mismos realicemos un programa de prueba con el
que observar cual es la estructura bsica 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 implementacin de la
aplicacin definitiva, y por tanto es necesario realizar otro programa de prueba
que contenga la misma estructura que el anterior pero con cdigo JAVA.
Para poder llevar a cabo este objetivo es necesario utilizar la librera
RXTXcomm como librera 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 estn obsoletos.
Una vez sabemos utilizar los recursos existentes de Java, se puede empezar a
desarrollar el software que nos ofrecer las opciones y caractersticas que
queremos implementar en la aplicacin definitiva.
El objetivo es que el programa pueda permitirnos, a travs de una interface
visual, realizar las siguientes tareas:

 Opciones para poder configurar los parmetros del puerto serie segn
convenga.
 Opciones para poder seleccionar los protocolos de comunicacin que sean
necesarios segn el vehculo.
 Realizar lectura de cdigos de error que pueda tener almacenados la
centralita electrnica del automvil.
 Realizar lecturas a tiempo real de los datos que aportan los diferentes
sensores del motor del vehculo, rpm, velocidad, carga del motor, etc.
 Disponer de una consola de texto que monitoree el puerto serie refrescando
su contenido segn el estado del trfico de datos entre el PC y el modem
interface.

13
2. Diseos
2.1. Metodologa utilizada
Durante el desarrollo de este proyecto se ha seguido en parte la filosofa de la
ingeniera inversa para alcanzar algunos de los objetivos, aunque tambin se
han seguido las pautas de diseos 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
tecnolgicamente como el del automvil 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 fsica, es decir, el hardware, se ha
utilizado un diseo de libre uso disponible en la red, a partir del cual se
construye bsicamente la interface. Este aparato tambin se comercializa
actualmente con el nombre de ALLProAdapter por la empresa OBDDiag.net y es
una versin compatible de otra interface llamada ELM327, que originalmente es
utilizada por muchos software disponibles de pago, y del cual tambin se
disponen de los diseos electrnicos, los cuales tambin se han aprovechado
para realizar el diseo final de la circuitera 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 garanta de que el hardware (interface con PIC18F2550 con
conexin USB), funciona correctamente y de que los programas en los que nos
basaremos para la realizacin del proyecto son funcionales. De no ser as,
podramos basarnos en herramientas que no serian tiles.
Una vez verificados estos puntos, el primer objetivo siempre ha sido conseguir
efectuar algn tipo de comunicacin 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 ms bsico, es decir,
constatar que el micro controlador reacciona o contesta de alguna manera
delante de un estimulo producido mediante una lnea de comunicaciones
digital.
Existe un software para el diagnostico de vehculos llamado ScanTool.net, que
en una de sus versiones ofrece el cdigo fuente, muy til para el propsito de
este proyecto. Este programa ha sido, para este proyecto, la base para poder
iniciar la bsqueda de los pasos que se siguen a la hora de realizar una
comunicacin desde el PC hasta la centralita electrnica del vehculo, atreves
del puerto de comunicaciones serie.
14
Adems 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 compaa Microchip, se pens en que posiblemente esta proporcionara su
driver, y aunque as es, lo proporciona mediante la instalacin de un paquete
de herramientas llamado USB Framework package, el cual obliga a instalar
adems del driver muchas otras utilidades que en principio no son necesarias
para este caso. La empresa que ofrece libremente la informacin para montar la
interface, OBDDiag.net, tambin proporciona el driver que se necesita, en forma
de fichero INF, y es suficiente para que Windows XP o Vista la detecte sin
problemas. Tambin 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, despus de montar la interface y verificar su funcionamiento


mediante el software ya existente, se procedi a intentar una comunicacin
utilizando recursos propios, es decir, sin recurrir a la funcionalidad de los
programas anteriores. Utilizando el cdigo fuente antes mencionado, el cual se
basa en C++, se diseo un programa de prueba que consegua comunicarse de
forma bsica con el microcontrolador, pero que aport mucha informacin para
realizar el proyecto.
Una vez lograda la comunicacin se procedi a intentar obtener el mismo
resultado pero utilizando la plataforma Java. Bsicamente 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 ms importante aqu fue encontrar
que mtodos utiliza Java para comunicarse con el puerto Serie, y aunque los
que proporciona Sun Microsystems, empresa diseadora de esta plataforma de
programacin, estn obsoletos, no fue difcil encontrar otros actualizados y
perfectamente compatibles con su mquina virtual. Esta funcionalidad la
proporciona el paquete RXTXcomm junto con la instalacin de la maquina
virtual de Java.

Como ltimo objetivo se plante realizar un software que ofreciese muchas ms


funcionalidades de configuracin sobre la interface, utilizando un entorno
grafico y mucho mas intuitivo. Este software engloba toda la capacidad de
comunicacin de los programas anteriores pero aadiendo todo el potencial
que ofrece un entorno visual diseado con java, lo cual dota al programa de
muchas opciones de configuracin y operatibilidad sobre la interface y por tanto
sobre la centralita electrnica de cualquier vehculo, que, al fin y al cabo, es lo
que se pretende controlar.
15
2.1 Recursos utilizados
Para realizar este proyecto se han utilizado recursos de diferente tipo segn si
nos referimos a la parte de software o a la de hardware, pero siempre
recurriendo como fuente principal de informacin 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 diseo del PCB necesarios
para construirla. Paralelamente tambin se sac informacin 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 electrnica (ECU) de cualquier vehculo utilizando los
microcontroladores que ellos suministran. El datasheet ELM327DS, es el
documento que expone todas las posibles ordenes y respuestas que se reciben
y envan al modem interface ELM327 y por tanto tambin al microcontrolador
que se utiliza en este proyecto, ya que este incorpora un firmware compatible
que contiene la misma estructura bsica 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:

16
17
A continuacin podemos ver uno de los esquemas elctricos que aporta ELM
Electronics, utilizando su microcontrolador ms famoso, el antes mencionado
ELM327, el cual utilizan muchas interfaces del mercado, ya que es capaz de
manejar y gestionar los protocolos de comunicacin ms utilizados en el
estndar OBD-II:

Detalle del esquema elctrico de un intrprete de OBD a RS232

18
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 cdigo fuente. Este cdigo fuente se trat con el tan extendido
programa de desarrollo DEV-C++, y posteriormente tambin se desarrollaron
con l los primeros diseos de prueba con los se empez la comunicacin con la
interface.

Una vez se empez a programar utilizando la plataforma JAVA y su mquina


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 versin
3.2.2, y fue muy til para desarrollar el entorno grfico del que dispone el
software de control que se ha creado en este proyecto.

Un recurso muy importante tambin fue toda la informacin que se aporta en


RXTX.org, donde se explica el funcionamiento de la librera RXTXcomm.jar, que
es la que se utiliza en JAVA para manejar los puertos serie. En esta web se
ofrecen claros ejemplos de cmo utilizar y configurar los mtodos de los que se
dispone, en especial haciendo hincapi en uno de ellos que ser adjuntado en el
anexo del proyecto.

19
Por otro lado para poder entender cmo funcionan los protocolos de
comunicacin que utiliza el estndar OBDII (On Borad Diagnostics II), se extrajo
mucha informacin 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 estndar, adems de documentos como (ASCII), que
detalla las equivalencias del cdigo ascii entre valores decimales y hexadecimal.

Detalle de equivalencias cdigo ASCII

Detalle de la informacin aportada en el documento OBD PIDs

20
2.3. Descripcin del diseo del modem interface
La primera parte del proyecto que se empez a disear y construir es el modem
interface que se utiliza como aparato para interconectar el PC con la centralita
electrnica del vehculo. 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 electrnica del vehculo con el modem y el modem propiamente
dicho. En los cables no hubo ningn proceso de montaje, se podan comprar ya
hechos, pero si se intento fabricar el del conector OBD-II, ya que es difcil
encontrarlos en los comercios especializados, pero se acab desechando por su
poca durabilidad ya que despus 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

21
Por tanto el trabajo importante aqu estaba en la fabricacin del modem. Para
poder construirlo se acudi a una tienda especializada donde disponan de
todos los componentes electrnicos necesarios, los cuales se procedieron a
instalar en el PCB creado a partir del siguiente layout de doble cara:

22
Este aparato contempla la posibilidad de utilizar 4 protocolos de comunicacin
distintos a nivel de capa fsica, ya que a lo largo de los aos las diferentes
centralitas electrnicas que montan los fabricantes de vehculos as lo han
dispuesto, aunque a partir del ao 2004, en Europa, la mayora de fabricantes
empezaron a implementar solo el protocolo CAN Bus. Cualquiera de los
vehculos fabricados en EE.UU. a partir del 1996, fueron obligados a disponer de
un puerto OBD2, y en Europa a partir del ao 2001, tambin se obligo a
implantar este tipo de conexin. La norma OBD2 comprende cuatro protocolos
de comunicacin 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 encarnacin ISO 14230 (AKA Keyword 2000) es el que la mayora
de vehculos europeos y asiticos utilizaban. Todos los nuevos modelos a partir
2007/2008 slo pueden implementar el protocolo CAN Bus. La siguiente imagen
es la de un conector tpico OBD2 de 16 pines instalado en cualquier vehculo:

Segn el protocolo de comunicacin que utilice el vehculo los pines habilitados


en el conector sern 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
alimentacin los pines 4 y 5 (masa chasis y masa seal respectivamente), y el pin
16 (+12V).

23
Para entender el funcionamiento interno del modem habra que empezar por
describir las partes de las que se compone su circuitera. En la siguiente imagen
se puede observar el esquema elctrico 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 adems de aportar un poco mas de memoria. Este
micro es el encargado de gestionar todo los componentes perifricos del
circuito y de mantener la comunicacin entre ellos, es decir, recibe la
informacin procedente del puerto USB al que est conectado, la transfiere a
los elementos del circuito que proceda y viceversa, ya que la comunicacin 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
seal diferencial de la entrada del PWM.

24
2.4 Descripcin del diseo del programador JDM2
Despus de la explicacin anterior es obvio deducir que el elemento ms
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 razn 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 estndar ICSP que es el que ofrece la
empresa Microchip para poder introducir los firmwares en los
microcontroladores que ellos fabrican. El esquema elctrico del programador es
de fcil adquisicin en cualquier web de electrnica y se representa con el
siguiente esquema:

25
El circuito se mont en una placa de baquelita especfica 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)

26
Adems del programador necesitamos poder conectarlo a una PC que disponga
de puerto serie, ya que a travs de este puerto se comunicar con el software
que enviar el firmware al micro. La aplicacin que se utiliz para programar el
microcontrolador fue PICPgm Develop. Programer que es un software gratuito
y de fcil manejo; solo hay que seleccionar el archivo que contenga el firmware
y una vez cargado cliquear en la opcin de gravado.

Siguiendo el datasheet del microcontrolador se conect al programador segn


el siguiente detalle:

Los pines detallados en la imagen son los que utiliza el programador JDM2 y por
tanto el estndar ICSP, para comunicarse con el PIC. Vemos que adems de los
pines de comunicacin (MCLR, PGC y PGD), tambin 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 programacin en modo Low-
Voltage ICSP, y en este caso se realiza en modo High-Voltage ICSP.

27
La conexin 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. Tambin 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 anomala en
el proceso de gravado.

28
2.5 Modificaciones del diseo del modem
Una vez se haba montado la interface y se procedi a comprobar su correcto
funcionamiento con software ya existente, se observ que funcionaba
correctamente en todos los vehculos chequeados los cuales utilizaban
diferentes protocolos de comunicacin, exceptuando uno de los casos que no se
obtena respuesta de su centralita electrnica. Se sospech que posiblemente la
interface no funcionaba correctamente y se procedi a analizar con un
osciloscopio las seales que produca 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
ms que correcto de la seal, ya que adems esta era de tipo no peridica y por
tanto con un osciloscopio analgico es prcticamente imposible capturarla.

El resultado fue el siguiente:

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

Resultado del trama enviada a travs del pin 10 (BUS-) del conector OBD-II

29
Para entender el resultado de estas graficas es preciso hacer una descripcin del
comportamiento de la capa fsica del protocolo j1850PWM. Este protocolo
dispone de dos lneas de comunicacin, el BUS+ y BUS-, y se caracteriza por
utilizar la modulacin del ancho de pulso (PWM) como mecanismo de
codificacin de bits. El periodo de cada bit tiene una duracin 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 proteccin contra interferencias exteriores.

Hecha esta explicacin podemos darnos cuenta de que la grfica que representa
el BUS+ desvela un pequeo problema elctrico, ya que mientras que el BUS-
reacciona rpidamente colocndose a 0 V, el BUS+ nunca llega a lograr los 5 V,
quedndose siempre en los 4,4 V aproximadamente. Aunque este no sera un
problema para realizar la comunicacin satisfactoriamente segn las
especificaciones del protocolo SAEJ1850PWM, ya que se encuentra dentro de
los mrgenes elctricos permitidos, se procedi a modificar la electrnica que se
ocupa de implementar esta codificacin.

30
En el esquema elctrico 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 diseo 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 . Adems se incorporaron resistencias de proteccin a las
bases de los transistores de 1K.

Por tanto la modificacin resultara segn el siguiente esquema:

31
Debido a que se constat que el problema no venia causado por el hardware se
empez a investigar si poda venir dado por errores en las tramas enviadas.
Segn el estndar J1850 PWM el formato de trama es el siguiente:

A partir de los documentos que explican las caractersticas 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 parmetros:

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


centralita con la interface, y segn 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 ms 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 mxima

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 mnima

32
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 direccin usada es fsica o funcional:


Y=0 Funcional Y=1 Fsica

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


mensaje:

Msg. KKYZ Respuesta(K) Direccin(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 Fsica Nodo a Nodo

5 0101 Requerido Fsica Reservado-MFG

6 0110 Requerido Fsica Reservado-SAE

7 0111 No requerido Fsica 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 Fsica Nodo a Nodo

13 1101 No requerido Fsica Reservado-MFG

14 1110 No requerido Fsica No disponible

15 1111 No requerido Fsica Reservado-MFG

33
 El segundo byte representa a la direccin de memoria elegida que
identifica a la centralita (ECU).

 El tercer byte representa a la direccin de memoria elegida que


identifica a la interface o herramienta de chequeo.

 Data Field: Es la informacin que se quiere hacer llegar al micro de la


ECU.

 CRC: Chequeo de redundancia cclica de la trama.

Conociendo ya la estructura de este protocolo se pens que una solucin al


problema sera modificar los Header Field ya que posiblemente no serian los
adecuados. A partir de aqu se procedi a averiguar cules 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,
despus 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 ms utilizada en muchas de las centralitas
que implementan el protocolo J1850PWM, pero tambin haca 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
direccin 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 (mnima), tres bytes de cabecera, tipo de mensaje 4, con
direccin fsica y nodo a nodo.

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


ATSH, pero por causas an 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 definan las cabeceras en
cuestin, y despus de una bsqueda muy extensa se encontraron y
modificaron con los nuevos valores.

34
En la siguiente captura podemos observar el fragmento de cdigo donde se
encontraban estos datos, fue un tarea laboriosa ya que este fichero solo
contiene tramas hexadecimales, y es el resultado de la compilacin de un
cdigo fuente al que no se tena acceso.
:103C70000350E66EE66A00010028BC6F000E0120CA
:103C8000BD6FBCC0E6FFBDC0E6FF040E0024BE6FE2
:103C9000000E0120BF6FBEC0E6FFBFC0E6FFDDEC37
:103CA0001EF046E90028E96E000E0120EA6E6A0E59
:103CB000EF6E020E0024E96E000E0120EA6E610E26
:103CC000EF6E030E0024E96E000E0120EA6EF10E85
:103CD000EF6E0001030EBC6F00EBE9FF01EBEAFFA2
:103CE000BC51EF2642E9E7CFD9FF1200D9CFE6FF5A

Adems de reemplazar estos bytes tambin se tuvo que recalcular el


checksum de cada lnea 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 comunicacin con la centralita en cuestin
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, segn el


documento J2178 una respuesta negativa significa que la centralita electrnica
no dispone de informacin sobre el modo de trabajo requerido, que es el
Modo 01.

35
El estndar OBD-II contempla varios modos de trabajo, entre ellos el modo 01,
modo 03, modo 07, modo 04, modo 09, modo 22 y bastantes ms. Cada uno de
ellos se ocupa de una parte de la informacin que puede aportar la ECU. El
modo ms extendido entre todas las centralitas es el modo 01.

Cada modo adems especifica sus parmetros PID (Parameter ID), en caso del
modo 01 uno puede ser el parmetro 00, que es el que se utiliza en nuestro
caso. Este parmetro 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.

Despus de consultar nuevamente el documento J2178 se averigu que cuando


el modo 01 no est disponible en la centralita lo ms probable es que se
implementara en su lugar el modo 22. Este fue el final de la investigacin ya que
el modo 22 utiliza una longitud de trama ms 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.

36
2.6 Diseo de la aplicacin de prueba en C++
Hasta ahora se ha explicado el diseo utilizado para crear la parte de hardware de la
que se compone el proyecto, pero anteriormente se ha hecho referencia tambin a la
parte de software que es la que tiene ms peso y elaboracin. El desarrollo del
software se empez a elaborar a partir del software libre ScanTool.net, que en una de
sus versiones ofrece el cdigo fuente. Utilizando la herramienta Dev-C++ y este
cdigo, el cual se basa en C++, se localizaron los mtodos y funciones que se
sospechaban eran los responsables de mantener la comunicacin mediante el puerto
serie. El primer paso fue averiguar cul era la funcin 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 funcin, tras esto el mismo
compilador mencionaba cuales eran las funciones y variables que llamaba este
mtodo para poder comunicarse, y por lo tanto poder buscarlas en el cdigo anterior
para reunirlas en el programa de prueba. Una vez que se tenan todas las funciones y
variables en el mismo fichero se poda compilar el cdigo sin obtener errores,
averiguando as cmo se comportaba el hilo de ejecucin. Despus de saber cul era
la rutina de ejecucin, se sacaron todas las rdenes o variables que no son
imprescindibles por realizar una comunicacin bsica, dejando la clase reducida al
mximo para tener una visin simple del proceso comunicacin dejando a la vista
claramente las funciones necesarias. Finalmente el programa de prueba poda
realizar la comunicacin enviando rdenes al PIC (atz, 0100, etc...) obteniendo los
mensajes enviados y los recibos con una visualizacin por consola. A continuacin
aparece el cdigo del programa de prueba:

37
38
Este programa utiliza la librera allegro como base, un librera muy utilizada
para desarrollar videojuegos, y por tanto era necesario indicarle al compilador
que la cargase con -lalleg, aunque tambin necesita cargar la librera
iostream y la winalleg, necesaria si se trabaja en Windows. Las funciones
implementadas son:

 main(): Arranca el hilo de ejecucin.

 init(): Carga las libreras y abre el puerto.

 deinit(): Descarga las libreras y cierra el puerto.

 read_comport(): Lee el puerto serie.

 open_comport(): Abre el puerto serie.

39
 close_commport(): Cierra el puerto serie.

 send_command(): Escribe en el puerto serie.

2.7. Diseo de la aplicacin de prueba en JAVA


El segundo diseo se centra en la elaboracin 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
libreras 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 libreras con esta funcionalidad.

Para este fin existe una librera llamada RXTXcomm, disponible en


www.RXTX.org, que mediante mtodos nativos dota a Java de la capacidad para
comunicarse con el puerto serie y paralelo, y adems 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, quedndose 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 libreras disponibles y podremos
utilizarla en el cdigo que programemos.

RXTX.org dispone de una web donde se explica el funcionamiento de la librera y


sus mtodos, adems ofrece ejemplos claros de cmo ponerla en marcha.

40
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);
}
}

41
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();
}
}

42
Estructuralmente el programa se asemeja al diseo en C++, y por tanto
implementa mtodos funcionalmente muy parecidos:

 public static void main(): Mtodo que inicia la ejecucin del programa.

 public void Conectar(): Establece la conexin 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(): Mtodo 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 segn el cdigo
ASCII, a partir de su equivalente en binario y posteriormente en hexadecimal.

Unos ejemplos de trama de datos y su tratamiento sera el siguiente:

 Comando a enviar: atz-> equivalencia cdigo ASCII:97,116,122


Este comando sirve para hacer un reset del micro.

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


atz\r->cdigo ASCII:97,116,122,13 y el mtodo write() de la clase
SerialPort la enva al puerto serie.

 Trama recibida del puerto serie atreves del mtodo 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 segn el cdigo ASCII: atz


ELM327 v1.1 compatible
El ltimo nmero (-1), indica que no se est recibiendo ningn dato, y
sirve como referencia para saber que la trama ha finalizado, adems el
micro marca el fin de la trama con el numero 62 ( equivalente a >).

43
 Comando a enviar: 01 0C-> equivalencia cdigo ASCII: 48,49,48,67
Este comando sirve para pedirle a la centralita electrnica del vehculo
(ECU), a cuantas revoluciones por minuto (rpm), est girando el motor.

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


01 0C\r->cdigo ASCII: 48,49,48,67,13 y el mtodo write() de la clase
SerialPort la enva al puerto serie.

 Posteriormente cuando la interface la ha recibido esta la enva a la ECU


segn 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 aade a la trama el comando
solicitado

 Trama recibida del puerto serie atreves del mtodo 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

44
 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 conexin, etc..)
41 0C: Confirmacin 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. Segn el documento
OBD Pids anteriormente mencionado, si pasamos a decimal estos
valores quedando en 11 y 136, y aplicamos esta frmula
(( A 256) + B ) = (11 256) + 136 = 738 , obtenemos las revoluciones por
4 4
minuto del motor a tiempo real.
0A: Chequeo de redundancia cclica de la trama (CRC).

45
2.5. Diseo de la aplicacin grafica diseada en JAVA
El diseo final y definitivo de este proyecto consista en realizar un software
multiplataforma diseado mediante la conocida estructura de programacin
por capas, para poder unir de forma correcta toda la capacidad de
comunicacin que se haba conseguido en los programas de prueba anteriores
con la necesidad de ofrecer muchas ms opciones, entorno grafico y el potencial
que aporta un entorno visual diseado con JAVA, lo cual dota al programa de
muchas posibilidades de configuracin y operatibilidad sobre la interface y por
tanto sobre la centralita electrnica de cualquier vehculo.
Este software intenta ser compatible con cualquier plataforma que disponga de
una conexin USB o RS-232, de ah su implementacin mediante JAVA, pero
debido a que para realizar las comunicaciones con dichos puertos se ha utilizado
un librera nativa (RXTXcomm.jar), es posible que existan algunas
incompatibilidades de un plataforma a otra, cosa que se debera consultar en la
web de RXTXcomm.

Bsicamente 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 conexin/desconexin con la interface y siempre viendo
en una consola de texto los datos que se estn enviando y recibiendo a
tiempo real.

 La opcin de configuracin del puerto: En esta seccin del programa


podemos configurar todos los parmetros necesarios del puerto serie,
para poder realizar una conexin.

 La opcin de seleccin del protocolo de comunicacin: Esta funcionalidad


del programa permite que el usuario pueda elegir manualmente el
protocolo con el que se quiere comunicar con la ECU de su vehculo.

 La opcin de Lectura de cdigos de error: Esta opcin ofrece la posibilidad


de poder averiguar si nuestro vehculo ha sufrido o sufre algn fallo
tcnico, a travs de la obtencin de un cdigo identificativo que
especifica la avera y que proporciona la ECU.

 La opcin de mediciones a tiempo real: Esta parte del programa


proporciona informacin de los diferentes sensores de los que dispone
el motor de nuestro vehculo, mostrando datos como la temperatura,
velocidad, revoluciones por minuto, cantidad de aire absorbido, etc.
46
Para realizar el software se utiliz la estructura de programacin por capas:
capa de datos, capa de dominio y capa de presentacin. Cada capa tiene una
funcin dentro del programa y una serie de clases que cumplen con la funcin
que se les ha asignado. A continuacin se explica la funcin 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 mandrselos a la interface a travs del puerto serie o
recibirlos y mandrselos a las capas superiores. En esta capa podemos
encontrar las siguientes clases:

 Clase Conexin: Es la encargada de encapsular todos los atributos


de los que se compone una conexin que se realiza atreves del
puerto serie: velocidad, dataBits, stopBits, paridad,
nombrePuerto, protocolo.

 Clase ControladorConexin: Contiene todos los mtodos


necesarios para realizar la conexin, 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 informacin que recibe con
la que dispone para poder reconocerla, como es el caso de la
lectura de los cdigos 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 presentacin. Ofrece la capacidad de trabajo de la capa de
datos, de una forma mucho ms accesible para sus capas superiores. En
esta capa encontramos la clase ControladorDominioConexin, la cual
contiene todos los mtodos necesarios para manejar todas las clases
que se encuentran en la capa de datos.

47
 Capa de Presentacin: 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
dems clases de la capa de presentacin y proporcionan las operaciones
bsicas del programa, como son poder iniciar o detener un conexin con
la interface y seleccionar las diferentes opciones del programa.
ControladorErrores y VistaCodigosError: Estas clases se ocupan de
gestionar la presentacin en pantalla de los cdigos de error
proporcionados por la ECU.
ControladorMediciones y VistaMediciones: Se ocupan de gestionar la
presentacin en pantalla de los datos referentes a valores que
proporcionan los sensores del vehculo, tales como temperatura,
velocidad, revoluciones por minuto, cantidad de aire absorbido, etc.
ControladorProtocolo y VistaProtocolo: Gestionan la presentacin en
pantalla de las opciones disponibles a la hora de seleccionar un
protocolo de comunicacin.
ControladorPSerie y VistaConfiguracin: Presentan en pantalla todas las
opciones que requiere el puerto serie para ser configurado. Adems
permiten realizar una bsqueda de estos.

Por lo extenso del cdigo de este ltimo programa, se incorporar al final del
proyecto como documento adjunto.

En esta aplicacin la clase ms importante y difcil de desarrollar es la clase


ControladorConexion, ya que es la que capacita al software de la capacidad de
utilizar varios hilos de ejecucin.
Esta clase implementa la interface Runnable con su respectivo mtodo
Run(), el cual est en permanente escucha a los mensajes que se envan desde
el puerto serie, y por tanto permite liberar al hilo principal para poder realizar
otras funciones simultneamente.
Otra de las clases que implementa un nuevo hilo de ejecucin 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
vehculo.
Por tanto en la aplicacin trabajan 3 hilos de ejecucin:
 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 ningn posible dato y una
velocidad de respuesta mucho ms alta.
 Hilo de la clase ControladorMediciones: Refresca constantemente en
pantalla los datos que va recibiendo el mtodo run() de la clase
ControladorConexin.
48
Cuando se procedi a probar el software sobre diferentes sistemas operativos
con la intencin 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 haba realizado la
programacin, 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 proceda a desconectarlo del puerto serie el
programa quedaba totalmente bloqueado.
Despus de muchas pruebas se averigu que las libreras nativas
RXTXcomm.jar que utiliza esta aplicacin se comportaban de diferente forma
segn el sistema operativo en el que estuviramos trabajando. El problema se
encontraba en el mtodo run() de la clase ControladorConexin(), ya que este
utiliza la clase SerialPort constantemente para escuchar el puerto serie.
Observando el siguiente fragmento de cdigo podemos hacernos una idea de la
situacin:
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 lnea subrayada, datosRecibidos.read(), es la orden que se
encarga de acceder al puerto y cuando el hilo de ejecucin llega a ella en
Windows la lee una vez y sigue su transcurso dentro del mtodo run() hasta el
siguiente ciclo de bucle donde lo volvera a leer, pero en Linux no sucede los
mismo, el hilo de ejecucin se detiene en esta lnea 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 aplicacin ya que nunca tendr permiso para
cerrarlo. Esto se solucion enviando un mensaje cualquiera al puerto y
cambiando en el mismo instante la condicin del bucle while(hilo=null), para
que el hilo de run() saliese de su estado de escucha y acabara extinguindose ya
que la condicin del bucle ya no se cumpla.
49
Como aporte final a esta aplicacin 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 aplicacin era que para poder comunicarse con los puertos de
comunicacin necesitaba la librera nativa RXTXcomm, y por tanto, esta no
viene incluida en las libreras 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 programacin no resulta


ser un problema, pero si para alguien que solo quiera hacer unas cuantas
pruebas.
La solucin fue crear una carpeta donde se introducira el archivo JAR, los
archivos adjuntos necesarios como los JPG y TXT, y otra carpeta donde
incluiramos la librera nativa RXTXcomm. Adems de lo anterior se crearon
dos archivos ejecutables (RunLinux.sh y RunWindows.bat), que se utilizan segn
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 cdigo de la


aplicacin.

 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 explicacin de cmo


arrancar el software.

 lib: Carpeta que contiene la librera nativa RXTXcomm con los


respectivos archivos rxtxParallel.dll, rxtxSerial.dll, librxtxSerial.so, y
librxtxParallel.so necesarios para realizar su carga en el sistema
operativo travs de la mquina virtual.

50
Para poder realizar la carga de la librera 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:

51
3. Resultados
3.1. mbito de utilizacin
Este proyecto se basa en un sistema para el chequeo del estado tcnico de
cualquiera de los vehculos que actualmente se comercializan o se han
comercializado desde 1996 en EEUU y 2001 en Europa, y por tanto su mbito de
utilizacin se puede extender bastante, incluso como pequea herramienta para
los profesionales del sector o para cualquier persona que disponga de un
vehculo dotado con el sistema On Board Diagnostics-II (OBD-II), que tenga
inters en indagar sobre el estado de su automvil.

Esta herramienta podra ser muy til, por ejemplo, para un pequeo taller
mecnico donde su presupuesto para adquirir un aparato de diagnostico es
reducido, y utilizando el sistema descrito aqu podra solucionarle muchos
problemas sin tener que hacer un gran desembolso econmico.

Actualmente todos los vehculos de cualquiera de los fabricantes, estn


obligados por ley a implementar este estndar, como un mecanismo que facilite
a todo el sector del mantenimiento, el rpido diagnostico de las averas, lo que
garantiza que el sistema que se ha desarrollado ser til en un mbito muy
extenso.

Tambin hay que decir que es necesario que el usuario tenga un mnimo de
conocimientos sobre la materia para comprender los resultados que muestra el
programa de diagnostico durante el chequeo del vehculo, lo que quizs 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 travs del puerto serie utilizando los lenguajes C++
y JAVA, informacin que puede ser muy til en todo aquel mbito que necesite
de esta conexin.

3.2. Validacin de los diseos


Una vez terminado el proceso de diseo, el siguiente paso ha sido validar el
proyecto realizando pruebas en diferentes vehculos de diferentes marcas,
teniendo la certeza de que estos estaban equipados con estndar OBD-II. Cada
modelo chequeado dispona de un protocolo de comunicacin diferente a nivel
de capa fsica, con lo que se consegua comprobar que todos los protocolos que
implementa la interface funcionan.

52
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.

53
3.3. Descripcin del funcionamiento
A continuacin se describen los pasos a seguir para poner en marcha el sistema
a la hora hacer un chequeo sobre un vehculo. 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 porttil o de uno de sobremesa
cercano al lugar donde estemos trabajando, conectamos la interface al puerto
USB. El montaje sera el siguiente si se realiza en un Citroen C3 del ao 2004, ya
que con respecto a otro modelo puede variar la localizacin del conector OBD-II.

54
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 sern utilizamos segn en el sistema
operativo en que estemos trabajando.
En este caso arrancamos RunWindows.bat y nos aparecer el siguiente entorno
visual:

55
El siguiente paso es realizar la conexin, y para ello debemos arrancar el motor
del coche, seleccionar los parmetros de configuracin 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 dems
parmetros segn sea necesario. Despus solo queda cliquear en Apply para
confirmar los cambios.

56
Ahora debemos seleccionar el protocolo de comunicacin (Options-
>Communication protocol configuration). En el caso de no conocer el protocolo
que se va utilizar, el sistema lo detectar automticamente:

Vemos que podemos seleccionar el protocolo de comunicacin o dejar


seleccionada la opcin Automatic detection of communication protocol, para
que sea autodetectado. Esta seccin tambin nos proporciona la posibilidad de
modificar las cabeceras de las tramas que se van a enviar. Cada opcin (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 parmetro y por tanto modificar el que se
enva por defecto.

57
El siguiente paso es iniciar la conexin 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 conexin correctamente y que la ECU
contest adecuadamente informando de los PIDs (Parameter IDs) que tiene
disponibles para ser inspeccionados.

58
En caso de que la conexin con la ECU sea fallida este sera 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 conexin a la ECU.

Los dems comandos AT, son contestados correctamente porque son datos
procedentes nicamente de la interface, es decir, solo incumben a parmetros
que tienen que ver con el microcontrolador de la interface sin tener en cuenta a
la ECU.

59
Ahora podemos ver un ejemplo de la informacin que nos dara el programa en
el caso de que el vehculo tuviera almacenados 4 cdigos de error indicando as
que se han producido estos fallos tcnicos. Para acceder a esta informacin 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 envan 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 cdigos de error tiene almacenados la ECU. Adems se detallan cuales
son los cdigos de error y una descripcin del significado de estos.
Si adems quisiramos borrar estas fallas almacenadas en la memoria de la
centralita, tendramos que cliquear en Clear error codes, y nos aparecera una
advertencia de seguridad que nos avisara del paso que vamos a realizar, ya que
si borramos esta informacin accidentalmente no la podramos recuperarla.

60
Otra funcionalidad del programa es la lectura de datos a tiempo real de los
sensores que tiene instalados el motor. La cantidad de informacin que
podemos obtener, depende de la ECU, ya que segn el modelo de esta, puede
ofrecer ms o menos datos de los sensores que gestiona en la mecnica del
motor. Un ejemplo sera el siguiente:

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


formato numrico, 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 caracterstica nos permite localizar rpidamente
cualquier incidencia en el proceso de transferencia de datos o en el
procesamiento de la centralita electrnica ya que de no ser as sera mucho ms
difcil detectar el problema.

61
En esta captura se observan ms datos aportados por la ECU:

Se puede observar que se nos proporciona informacin sobre la cantidad de


kilmetros que hemos circulado con algn problema tcnico indicado con la luz
de chequeo MIL (Malfunction Indicator Lamp) encendida.
Otro dato importante es el de la presin que hay en el circuito de inyeccin 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 presin, pero teniendo en cuenta que la tecnologa hoy
utilizada puede llegar hasta los 2000 bar en el rgimen de motor ms alto, es
bastante aceptable.

62
En esta otra imagen se observan las mismas lecturas pero realizadas a un
rgimen de motor ms 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 sealar es que adems de ver cambios en la rpm, tambin los hay en MAF
Air Flow Rate ya que el motor necesita absorber ms aire. En Calculated
engine load value los datos tambin varan, 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 podra soportar, y aunque lo lgico sera que aumentase a mas
revoluciones el resultado es todo lo contrario, disminuye. Esto se debe a que
aunque el motor gira a ms vueltas, este no debe ejercer ningn esfuerzo ya
que se encuentra parado y por tanto no encuentra ninguna fuerza contraria al
sentido de giro.

63
Una imagen muy determinante para constatar que las lecturas son correctas es
la siguiente:

Observamos que el cuenta revoluciones del panel de instrumentos del vehculo,


est marcando alrededor de las 1500 rpm, dato que se confirma observando la
pantalla del ordenador porttil donde aparece una lectura de 1510 rpm. Se
observa tambin que hay coincidencia en la velocidad, que es de 0 km/h ya que
nos encontrbamos parados.

64
Hasta ahora el software se ha presentado funcionando bajo sistema operativo
Windows XP, pero tambin 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 diseado en este proyecto bajo


sistema operativo Linux, concretamente en la distribucin Ubuntu en su versin
8.04, con la maquina virtual de JAVA instalada.

Respecto a Linux hay que hacer una pequea aclaracin sobre la deteccin 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 adems se ubican en un carpeta
llamada /dev. Por tanto cuando arrancamos el programa en Linux
seleccionamos una de estas opciones y no tendremos ningn 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.

65
Muchas de las interface compatibles utilizan el puerto USB, como es nuestro
caso, y en Windows las detecta tambin 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 librera nativa RXTXcomm, la cual no contempla este tipo de puertos.
Para poder solucionarlo podemos ejecutar la siguiente lnea de comando en un
terminal de Linux, con la intencin de hacer un linkado simblico de la interface
/dev/ttyACM0 con una referencia que si reconozca la librera, por ejemplo
/dev/ttyS0:

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

Despus de ejecutar este comando podremos seleccionar el dispositivo ttyS0


como si se tratase de ttyACM0, y la comunicacin se realizar sin ningn 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
diseado es aplicable al chequeo del estado tcnico de cualquiera de los
vehculos que actualmente se comercializan o se han comercializado desde el
ao 1996 en EEUU y 2001 en Europa. Es a partir de estas fechas cuando se
oblig a los fabricantes a implantar el estndar OBD-II, y aunque anteriormente
los vehculos tambin estaban equipados con un sistema de este tipo
precisamente llamado OBD, es decir, el mismo sistema pero en su primera
versin, 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 vehculos.

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 vehculos mencionados anteriormente averiado y que despus de su
reparacin verifique con esta herramienta si el problema se ha subsanado
correctamente asegurndose de que la ECU no devuelve ningn cdigo de error
o de que el sensor en cuestin ofrece unas lecturas correctas segn
especificaciones del fabricante.

66
Otro ejemplo podra ser el que se da normalmente cuando cualquier poseedor
de un vehculo 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
cdigo 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 inters quieren conectarse con su automvil
para observar los datos que la centralita electrnica 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 mecnica.

4. Comentarios finales
4.1 Plan de trabajo
El plan de trabajo de este proyecto se ha ido desarrollando segn los siguientes
puntos:

1. Conseguir todos los componentes y materiales electrnicos necesarios


para construir el modem interface y el programador de PICs.

2. Montar la interface y el programador segn el PCB y esquemas elctricos


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 porttil 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.
67
7. Conectar la interface a diferentes vehculos para asegurar su
funcionalidad.

8. Programar aplicaciones de prueba en C++ y Java.

9. Programar aplicacin utilizando JAVA con un entorno visual lo


suficientemente potente que permita gobernar la interface y la
centralita electrnica de forma estable.

10. Verificar el correcto funcionamiento de la aplicacin sobre la interface


mediante pruebas.

11. Verificar el correcto funcionamiento de la aplicacin sobre la centralita


electrnica de los vehculos mediante pruebas.

12. Verificar el correcto funcionamiento de la aplicacin 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

68
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 100F 16V

C3 22F 6.3V

R3 100

R1 1.5K

R2 10K

69
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 edicin de archivos en formato


hexadecimal.

 PICPgm Programer: Utilizado para el gravado del firmware en el


PIC18F2550.

 GerbMagic: Programa utilizado para la edicin y diseo del circuito


electrnico del modem interface.

 JDK 6 Update 13: Paquete instalador de la mquina virtual de JAVA.

 PC de sobremesa con WindowsXP Home Edition y Linux Ubuntu 8.04


instalados para realizar la programacin.

 Ordenador porttil con WindowsXP Home Edition Y Linux Ubuntu 8.04


instalados para realizar las pruebas en los vehculos.

4.3 Presupuesto
La tabla siguiente especifica el presupuesto detallado en euros:

Referencia Cantidad Precio unitario Precio total

Material montaje interface 1 20 20

Material montaje programador 1 5 5

Cable OBD-II a DB9 hembra 1 5 5

Cable USB tipo A-B 1 2 2

Hora trabajo 35 30 1050

Total 1082

70
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
continuacin 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 electrnicas (ECU), segn el estndar


OBD-II.

 Consolidar la comunicacin con el modem a travs del puerto serie


mediante aplicaciones de software de propio desarrollo en C++ y JAVA.

 Conseguir descifrar las tramas digitales para obtener una informacin


fcilmente comprensible en pantalla de los datos enviados por la ECU.

 Finalizar el desarrollo de la aplicacin visual en JAVA con todas las


opciones previstas.

 Estabilizar la aplicacin visual en JAVA sin que se produzca ningn error


ya sea de comunicacin con la interface o de manejo respecto al usuario.

 Conseguir que la aplicacin visual en JAVA funcione correctamente tanto


en Windows como en Linux.

4.5 Conclusiones
 El lenguaje de programacin JAVA es una herramienta muy potente, ya
que permite que una misma aplicacin pueda funcionar de igual forma
en diferentes sistemas operativos y plataformas.

 Es posible acceder a la centralita electrnica de un vehculo utilizando


montajes sencillos y ordenadores personales. En realidad est al alcance
de cualquier usuario particular.
71
 La ingeniera inversa sobre un firmware (desensamblado), tiene
limitaciones y para realizar cambios significativos es necesario disponer
del cdigo fuente, sino estamos limitados a pequeas modificaciones.

 Los fabricantes de automviles han implementado el estndar OBD-II


obligados por EE.UU. i U.E de una forma bastante compatible como lo
demuestra el que un pequeo dispositivo genrico como el que se ha
realizado, funcione en un amplio rango de vehculos.

 El hecho de disponer de un microcontrolador programable disminuye la


dependencia en la plataforma, ya que solo es necesario que disponga de
conexin USB, y a partir de aqu el papel de las plataformas es de
gestionar una conexin serie. El procesado de los protocolos los realiza
el micro.

4.6. Mejoras futuras


 Internacionalizar el software de control con la intencin de que pueda
mostrar la informacin en varios idiomas ya que en esta primera versin
solo se muestran en ingles.

 Implementar todos los modos de trabajo del estndar OBD-II en el


software de control.

 Dotar a la interface de una botonera y un pequeo display para poder


realizar las funciones ms simples de forma autnoma, como por
ejemplo la lectura y borrado de los cdigos de error DTC.

 Implementar en el software de control una opcin de autoayuda para


poder entender y manejar el sistema de forma ms rpida. Esta mejora
sera muy til porque los datos que se manejan son bastante abstractos.

 Crear un paquete instalador que automticamente site los ficheros


necesarios del software para acelerar su puesta en marcha.

72
Bibliografa
[1] OBD2 ELM327 compatible AllPro adapter with USB, www.obddiag.net

[2] OBD-II PIDs, 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]Librera nativa RXTXcomm, www.rxtx.org

73
Anexo
Cdigo ejemplo para el manejo de la librera 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 Exception
{
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if ( portIdentifier.isCurrentlyOwned() )
{
System.out.println("Error: Port is currently in use");
}
else
{
CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
if ( commPort instanceof SerialPort )
{
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(57600,SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();

(new Thread(new SerialReader(in))).start();


(new Thread(new SerialWriter(out))).start();

}
else
{
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}

74
public static class SerialReader implements Runnable
{
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(buffer,0,len));
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}

public static class SerialWriter implements Runnable


{
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();
}
}
}

75
Cdigo fuente del software de control desarrollado en el proyecto:

Capa de Datos:
Clase Conexin:
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 protocolo) {
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;
}

76
Clase ControladorConexin:
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";
77
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 resetea
//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 pararlo 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 {

78
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.

79
} 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){

80
//El siguiente metodo diferencia las 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 lineas 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
}

81
}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 = (CommPortIdentifier) 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 02 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){

82
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

83
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
//principio 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);
}
});
}

84
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(){}

85
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 doesn't have any
error code stored";
}else{
numeroErrores=valorDec-128;
estadoErrores= "The check engine light (MIL) is ON, and the ECU has
"+numeroErrores+" error code/s stored";
}
return estadoErrores;

}
public String descifraTramaHexDescripcionErrores(String error){
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));
}

86
}
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
//cdigo procedente de la ECU
valorHex.delete(0, longitudTrama);
}

return codigoError.toString();
}
}

87
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;
}
88
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 ControladorDominioConexin:
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 respuestaTexto) {


contCon = new ControladorConexion(respuestaTexto);
}

public void establecerConexion(int velocidad,int dataBits,int stopBits,int


paridad,String nombrePuerto,String protocolo){
con = new Conexion(velocidad,dataBits,stopBits,paridad,nombrePuerto,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();
}

89
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 Presentacin:

Clase ConfirmacinBorradoErrores:
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());
90
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;
}

91
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 contDom,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;
}
92
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 contDom){


VMed = new VistaMediciones();
this.contDom = contDom;
df = new DecimalFormat("0.0");//Especifica los decimales mostrados en las TextField.
eventos();
}

93
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");

94
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;

95
}
}
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);

96
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;

97
}
}
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");

98
}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);

99
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){

100
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;
}
}

101
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);

102
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){

103
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)+"%");

104
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){

105
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");

106
}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;
107
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);
}

108
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();
}
});

109
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;

110
public class ControladorProtocolo {

VistaProtocolo VProt;
String protocolo;
ControladorDominioConexion contDom;

public ControladorProtocolo(ControladorDominioConexion contDom){


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) {

111
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);
}
}
});
}
}

112
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 contDom){

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.pars
eInt((String)VC.getJComboBoxDataBits().getSelectedItem()),(VC.getJComboBoxStopBits().getSele
ctedIndex())+1,VC.getJComboBoxParidad().getSelectedIndex(),VC.getJComboBoxNombrePort().getSe
lectedItem().toString(),"0100");
}

}
113
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.HORIZONT
AL_SCROLLBAR_ALWAYS);
jScrollPaneErrores.setBounds(new Rectangle(7, 7, 784, 637));
}
return jScrollPaneErrores;
}

114
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","/d
ev/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","1920
0","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();
}

115
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;
}

116
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;
}

117
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;
118
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;

119
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);

120
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();

121
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));

122
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;
}

123
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();

124
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));

125
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);

126
}
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();

127
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;
}

128
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();

129
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));

130
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);
}

131
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() {

132
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));

133
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);

134
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;

135
}

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() {

136
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));

137
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);

138
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) {

139
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);

140
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);

141
}
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;

142
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());

143
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;
}

144
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_SCRO
LLBAR_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));

145
}
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;
146
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());

147
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;
}

148
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() {

149
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;
}

150

Das könnte Ihnen auch gefallen