Documentos de Académico
Documentos de Profesional
Documentos de Cultura
4 DE JUNIO DE 2009
2
ÍNDICE
1. Introducción 5
1.2. Antecedentes…………………………………………………………..6
1.3. Objetivos………………………………………………………………..10
2. Diseños realizados 14
3
3. Resultados 52
4. Comentarios finales 67
4.3. Presupuesto………………………………………………………………..70
4.5. Conclusiones……………………………………………………………….71
5. Bibliografía 73
6. Anexo 74
4
1. Introducción
1.1. Justificación del proyecto
La motivación principal de este proyecto es llegar a poder diseñar un sistema
con el que poder diagnosticar las posibles averías de cualquier vehículo sin
tener que recurrir a los costosos servicios oficiales.
En realidad estos módulos no son más que una pequeña computadora a la cual
si se conoce su funcionamiento se puede acceder aunque su fabricante intente
taparlo, cosa que no les es posible ya que desde hace ya bastantes años están
obligados a implementar un estándar de autodiagnóstico llamado “OBD-II”, que
se hizo público a consecuencia de las grandes emisiones contaminantes a las
que estamos expuestos, implantando así un mecanismo de control de estas.
5
1.2. Antecedentes
OBD (On Board Diagnostics) es un sistema de diagnóstico a bordo en vehículos
(coches y camiones). Actualmente se emplea OBD-II (Estados Unidos), EOBD
(Europa), y JOBD (Japón) estándar que aportan un control casi completo del
motor y otros dispositivos del vehículo. OBD II es la abreviatura de On Board
Diagnostics (Diagnóstico de Abordo) II, la segunda generación de los
requerimientos del equipamiento autodiagnosticable de abordo de los Estados
Unidos de América. Las características de autodiagnóstico de a bordo están
incorporadas en el hardware y el software de la computadora de abordo de un
vehículo para monitorear prácticamente todos los componentes que pueden
afectar las emisiones. Cada componente es monitoreado por una rutina de
diagnóstico para verificar si está funcionando perfectamente. Si se detecta un
problema o una falla, el sistema de OBD II ilumina una lámpara de advertencia
en el cuadro de instrumentos para avisarle al conductor.
6
los sensores expectadas basados en las condiciones de operación del motor, y
los componentes se adaptan al sistema calibrándose empíricamente. Esto
significa que los repuestos necesitan ser de alta calidad y específicos para el
vehículo y modelo.
Modo 02: Muestra los llamados en este contexto “Freeze Frame Data”, es
decir, capturas puntuales de información que ha ido almacenado la ECU.
Modo 04: Se utiliza para borrar los códigos de error almacenados (DTC) y
los datos “Freeze Frame Data”.
Modo 05: Muestra los valores tomados a los sensores de oxigeno y los
resultados de los test que les ha realizado de forma autónoma la ECU.
Modo 06: Se usa para obtener los resultados de los test realizados por la
ECU al sistema de monitoreo no continuo. Existe normalmente un valor
mínimo, máximo y actual de cada uno de los test.
En este proyecto solo se va ha hacer uso del modo 01, 03 y 04, aunque teniendo
en cuenta que el modo 01 dispone de más de 60 PID’s diferentes, no es poco el
trabajo a desarrollar.
7
Actualmente ya existen muchas herramientas y software disponible para poder
llevar a cabo la inspección de un vehículo dotado de OBD-II. Existen muchos
tipos de herramientas distintas, pero principalmente la gran diferencia entre
ellas es si pueden o no trabajar de forma autónoma, es decir, si necesitan o no
ser ejecutadas en un ordenador personal bajo un sistema operativo.
8
También podemos encontrar el software ScanTool.net, el cual ha sido de mucha
utilidad para este proyecto ya que en una de sus versiones ofrece el código
fuente con el que fue diseñado:
Interface ELM327
9
Interface ELM327 Interface ELM327 con Bluetooth
En las imágenes vemos que los modelos tienen diferentes formas y diferentes
métodos de conexión, ya que en uno de los casos se realiza por “bluetooth”,
pero su funcionamiento respecto al estándar OBD-II es idéntico.
1.3. Objetivos
Este proyecto abarca una pequeña parte del complejo campo de la
autodiagnosis en la automoción, y por tanto no pretende crear un sistema que
pueda substituir a las avanzadas herramientas de las que dispone cualquier
servicio de manteniendo, ya que el estándar OBD-II, aun siendo de libre acceso,
comprende modos de trabajo de los cuales no se tiene información en este
proyecto. Mucha de la documentación que engloba al OBD-II está disponible
previo pago a las respectivas empresas que lo han diseñado y estandarizado,
como es el caso de la Sociedad Americana de Ingenieros (SAE) o la Organización
Internacional para la Estandarización (ISO). Aun no disponiendo de toda la
información deseada los objetivos de este proyecto son bastante ambiciosos y
se pueden listar como sigue:
10
Realizar mejoras en el hardware ya existente en el mercado a partir del
cual se construirá nuestra interface.
Este sistema utiliza por un lado un modem interface que adecua las señales
procedentes de la centralita electrónica que se encuentra en el vehículo (ECU), a
las señales que necesita un puerto USB de cualquier ordenador. A partir de aquí,
un software de control gestionara toda la información recibida. Muchos de los
métodos de diagnostico existentes utilizan este planteamiento pero ninguno de
ellos, por lo menos oficialmente, utiliza una aplicación desarrollada en JAVA
que, por lo tanto, permita ejecutarse en la mayoría de los sistemas operativos
existentes, incluyendo el famoso Linux y además en diferentes tipos de
plataformas.
11
1.5. Descripción general del proyecto
En este proyecto como se ha ido comentado a lo largo de este documento se
pretende elaborar un sistema capaz de comunicarse con la electrónica que
gestiona cualquiera de los vehículos dotados con el estándar OBD-II, y para
llevarlo acabo ha sido necesario trabajar sobre diferentes aspectos que están
involucrados en el proceso de comunicación. Por tanto principalmente existen
dos partes importantes a diferenciar en el desarrollo de este proyecto:
12
1.5.2 Descripción básica del software (Interface Visual)
Para realizar la aplicación que gestionará el modem y todos los datos que serán
enviados y recibidos a través de él, se deben realizar primero unos pasos previos
para poder familiarizarse con las rutinas que deberemos utilizar. Como inicio de
este proceso se debe comenzar por averiguar cuál es el mecanismo que siguen
otras aplicaciones que ya implementan este mecanismo, y para poder hacerlo
existe una aplicación, mencionada anteriormente (ScanTool), que ofrece el
código fuente mediante lenguaje C++. A través de este código es posible extraer
las rutinas básicas con las que se realiza la comunicación con el micro y la ECU,
esto permite que nosotros mismos realicemos un programa de prueba con el
que observar cual es la estructura básica que debemos seguir.
Debido a que el objetivo es realizar el software utilizando JAVA, ya que nos
permitirá hacer portable nuestro trabajo a diferentes plataformas, el programa
anterior no es aun suficiente para poder afrontar la implementación de la
aplicación definitiva, y por tanto es necesario realizar otro programa de prueba
que contenga la misma estructura que el anterior pero con código JAVA.
Para poder llevar a cabo este objetivo es necesario utilizar la librería
“RXTXcomm” como librería nativa para realizar las comunicaciones por los
puertos serie, ya que los medios que ofrece la “API” de Java respecto a este tipo
de comunicaciones están obsoletos.
Una vez sabemos utilizar los recursos existentes de Java, se puede empezar a
desarrollar el software que nos ofrecerá las opciones y características que
queremos implementar en la aplicación definitiva.
El objetivo es que el programa pueda permitirnos, a través de una interface
visual, realizar las siguientes tareas:
Opciones para poder configurar los parámetros del puerto serie según
convenga.
Opciones para poder seleccionar los protocolos de comunicación que sean
necesarios según el vehículo.
Realizar lectura de códigos de error que pueda tener almacenados la
centralita electrónica del automóvil.
Realizar lecturas a tiempo real de los datos que aportan los diferentes
sensores del motor del vehículo, rpm, velocidad, carga del motor, etc.
Disponer de una consola de texto que monitoree el puerto serie refrescando
su contenido según el estado del tráfico de datos entre el PC y el modem
interface.
13
2. Diseños
2.1. Metodología utilizada
Durante el desarrollo de este proyecto se ha seguido en parte la filosofía de la
ingeniería inversa para alcanzar algunos de los objetivos, aunque también se
han seguido las pautas de diseños anteriores de disponibilidad libre que realizan
las mismas funciones, ya que encontrar cual es el camino que se sigue para
realizar los procesos adecuadamente en un sector tan cerrado
tecnológicamente como el del automóvil puede llegar a ser muy desesperante.
Este proyecto consta principalmente de un parte de software y otra de
hardware. En lo que hace referencia a la parte física, es decir, el hardware, se ha
utilizado un diseño de libre uso disponible en la red, a partir del cual se
construye básicamente la interface. Este aparato también se comercializa
actualmente con el nombre de ALLProAdapter por la empresa OBDDiag.net y es
una versión compatible de otra interface llamada ELM327, que originalmente es
utilizada por muchos software disponibles de pago, y del cual también se
disponen de los diseños electrónicos, los cuales también se han aprovechado
para realizar el diseño final de la circuitería del modem interface basado en el
PIC18F2550.
El primer paso ha sido comprobar que los programas que existen como
antecedentes funcionen correctamente sobre el hardware montado. De esta
manera se tiene la garantía de que el hardware (interface con PIC18F2550 con
conexión USB), funciona correctamente y de que los programas en los que nos
basaremos para la realización del proyecto son funcionales. De no ser así,
podríamos basarnos en herramientas que no serian útiles.
Una vez verificados estos puntos, el primer objetivo siempre ha sido conseguir
efectuar algún tipo de comunicación con el dispositivo (PIC18F2550) desde el
PC, ya que uno de los problemas comunes a todos los dispositivos de este tipo
es conocer la forma de comunicarse desde el nivel más básico, es decir,
constatar que el micro controlador reacciona o contesta de alguna manera
delante de un estimulo producido mediante una línea de comunicaciones
digital.
Existe un software para el diagnostico de vehículos llamado ScanTool.net, que
en una de sus versiones ofrece el código fuente, muy útil para el propósito de
este proyecto. Este programa ha sido, para este proyecto, la base para poder
iniciar la búsqueda de los pasos que se siguen a la hora de realizar una
comunicación desde el PC hasta la centralita electrónica del vehículo, atreves
del puerto de comunicaciones serie.
14
Además del software de control y el hardware a controlar hay que tener en
cuenta que los microcontroladores necesitan un “driver” para que el sistema
operativo que lo gestiona pueda controlarlo. Dado que el PIC18F2550 lo fabrica
la compañía Microchip, se pensó en que posiblemente esta proporcionara su
“driver”, y aunque así es, lo proporciona mediante la instalación de un paquete
de herramientas llamado “USB Framework package”, el cual obliga a instalar
además del driver muchas otras utilidades que en principio no son necesarias
para este caso. La empresa que ofrece libremente la información para montar la
interface, OBDDiag.net, también proporciona el driver que se necesita, en forma
de fichero INF, y es suficiente para que Windows XP o Vista la detecte sin
problemas. También se pudo averiguar que en otros sistemas operativos,
como por ejemplo Linux, este microcontrolador está contemplado y en las
mismas distribuciones de Linux ya se incorpora el “driver” necesario.
Como último objetivo se planteó realizar un software que ofreciese muchas más
funcionalidades de configuración sobre la interface, utilizando un entorno
grafico y mucho mas intuitivo. Este software engloba toda la capacidad de
comunicación de los programas anteriores pero añadiendo todo el potencial
que ofrece un entorno visual diseñado con java, lo cual dota al programa de
muchas opciones de configuración y operatibilidad sobre la interface y por tanto
sobre la centralita electrónica de cualquier vehículo, que, al fin y al cabo, es lo
que se pretende controlar.
15
2.1 Recursos utilizados
Para realizar este proyecto se han utilizado recursos de diferente tipo según si
nos referimos a la parte de software o a la de hardware, pero siempre
recurriendo como fuente principal de información a la que se dispone en la red.
Para montar la interface se recurrió a la web OBDDiag.net, donde se describen
todos los materiales, software, firmware del micro y diseño del PCB necesarios
para construirla. Paralelamente también se sacó información de la web ELM
Electronics, donde mediante los datasheet que ofrecen (ELM327DS.pdf y
ELM320DS.pdf), describen como fabricar un interface para conectarse a la
centralita electrónica (ECU) de cualquier vehículo utilizando los
microcontroladores que ellos suministran. El datasheet ELM327DS, es el
documento que expone todas las posibles ordenes y respuestas que se reciben
y envían al modem interface ELM327 y por tanto también al microcontrolador
que se utiliza en este proyecto, ya que este incorpora un firmware compatible
que contiene la misma estructura básica que el original, el ELM327.
En el siguiente listado se pueden ver todos los posibles comandos que el
ELM327 implementa, y por tanto, aunque no todos los comandos que utiliza la
interface utilizada en este proyecto:
16
17
A continuación podemos ver uno de los esquemas eléctricos que aporta ELM
Electronics, utilizando su microcontrolador más famoso, el antes mencionado
ELM327, el cual utilizan muchas interfaces del mercado, ya que es capaz de
manejar y gestionar los protocolos de comunicación más utilizados en el
estándar OBD-II:
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 código fuente. Este código fuente se trató con el tan extendido
programa de desarrollo DEV-C++, y posteriormente también se desarrollaron
con él los primeros diseños de prueba con los se empezó la comunicación con la
interface.
19
Por otro lado para poder entender cómo funcionan los protocolos de
comunicación que utiliza el estándar OBDII (On Borad Diagnostics II), se extrajo
mucha información de la enciclopedia libre Wikipedia, donde en uno de sus
documentos (OBD-II PIDs), explica cuales y como son los formatos de trama de
datos que utiliza este estándar, además de documentos como (ASCII), que
detalla las equivalencias del código ascii entre valores decimales y hexadecimal.
20
2.3. Descripción del diseño del modem interface
La primera parte del proyecto que se empezó a diseñar y construir es el modem
interface que se utiliza como aparato para interconectar el PC con la centralita
electrónica del vehículo. Este aparato consta de tres partes a diferenciar, el
cable USB que comunica el PC con el modem, el cable OBD-II que comunica la
centralita electrónica del vehículo con el modem y el modem propiamente
dicho. En los cables no hubo ningún proceso de montaje, se podían comprar ya
hechos, pero si se intento fabricar el del conector OBD-II, ya que es difícil
encontrarlos en los comercios especializados, pero se acabó desechando por su
poca durabilidad ya que después de unas pocas pruebas empezó a deteriorarse.
(J2850 BUS+) 2 7
(J2850 BUS- ) 10 6
(Battery Power) 16 9
21
Por tanto el trabajo importante aquí estaba en la fabricación del modem. Para
poder construirlo se acudió a una tienda especializada donde disponían de
todos los componentes electrónicos necesarios, los cuales se procedieron a
instalar en el PCB creado a partir del siguiente “layout” de doble cara:
22
Este aparato contempla la posibilidad de utilizar 4 protocolos de comunicación
distintos a nivel de capa física, ya que a lo largo de los años las diferentes
centralitas electrónicas que montan los fabricantes de vehículos así lo han
dispuesto, aunque a partir del año 2004, en Europa, la mayoría de fabricantes
empezaron a implementar solo el protocolo CAN Bus. Cualquiera de los
vehículos fabricados en EE.UU. a partir del 1996, fueron obligados a disponer de
un puerto OBD2, y en Europa a partir del año 2001, también se obligo a
implantar este tipo de conexión. La norma OBD2 comprende cuatro protocolos
de comunicación distintos:
ISO 9141/14230
J1850 PWM
J1850 VPW
VPW (Variable Pulse Width) fue originalmente introducido por General Motors,
mientras que PWM (Pulse Width Modulation) pertenece al grupo Ford. ISO 9141
y la posterior encarnación ISO 14230 (AKA Keyword 2000) es el que la mayoría
de vehículos europeos y asiáticos utilizaban. Todos los nuevos modelos a partir
2007/2008 sólo pueden implementar el protocolo CAN Bus. La siguiente imagen
es la de un conector típico OBD2 de 16 pines instalado en cualquier vehículo:
El protocolo ISO 9141/14230 utiliza los pines 6 y 15, el protocolo J1850 PWM
utiliza el 2 y el 10, el protocolo J1850 VPW utiliza solo el pin 2, y el protocolo ISO
15765 (CAN), el pin 6 y 14. Todos los protocolos utilizan como fuente de
alimentación los pines 4 y 5 (masa chasis y masa señal respectivamente), y el pin
16 (+12V).
23
Para entender el funcionamiento interno del modem habría que empezar por
describir las partes de las que se compone su circuitería. En la siguiente imagen
se puede observar el esquema eléctrico de la interface:
La parte del circuito que se ocupa de manejar el protocolo CAN BUS, son los
integrados MCP2515 y MCP2551, el integrado MC33290 maneja el protocolo
ISO9141/14230 junto con Q3, J1850 VPW está controlado por MC33390 y el par
de Mosfets (Q2 P-channel y Q1 N-channel) controlan el bus J1850PWM junto
un comparador interno del PIC18F2550 y las resistencias R4 y R5 que crean la
señal diferencial de la entrada del PWM.
24
2.4 Descripción del diseño del programador JDM2
Después de la explicación anterior es obvio deducir que el elemento más
importante aquí es el microcontrolador PIC18F2550, pero por si solo no tiene
ninguna funcionalidad a no ser que se le introduzca el firmware adecuado, por
esta razón se tuvo que construir exclusivamente para este fin un programador
compatible con el protocolo ICSP (In-Circuit Serial Programming). Este tipo de
programador, llamado JDM2, es muy famoso en la red ya que se construye con
pocos componentes e implementa el estándar ICSP que es el que ofrece la
empresa Microchip para poder introducir los firmwares en los
microcontroladores que ellos fabrican. El esquema eléctrico del programador es
de fácil adquisición en cualquier web de electrónica y se representa con el
siguiente esquema:
25
El circuito se montó en una placa de baquelita específica para realizar
prototipos, y se siguió el siguiente “layout”:
26
Además del programador necesitamos poder conectarlo a una PC que disponga
de puerto serie, ya que a través de este puerto se comunicará con el software
que enviará el firmware al micro. La aplicación que se utilizó para programar el
microcontrolador fue “PICPgm Develop. Programer” que es un software gratuito
y de fácil manejo; solo hay que seleccionar el archivo que contenga el firmware
y una vez cargado cliquear en la opción de gravado.
Los pines detallados en la imagen son los que utiliza el programador JDM2 y por
tanto el estándar ICSP, para comunicarse con el PIC. Vemos que además de los
pines de comunicación (MCLR, PGC y PGD), también utiliza el puerto serie para
alimentarse mediante los pines 8 y 19 para masa, y el 20 para los +5 V
necesarios. El pin 26 (PGM), no está implementado en el programador ya que
este solo se utiliza en el caso que se realice una programación en modo “Low-
Voltage ICSP”, y en este caso se realiza en modo “High-Voltage ICSP”.
27
La conexión realizada para proceder a programar el micro fue la siguiente:
28
2.5 Modificaciones del diseño del modem
Una vez se había montado la interface y se procedió a comprobar su correcto
funcionamiento con software ya existente, se observó que funcionaba
correctamente en todos los vehículos chequeados los cuales utilizaban
diferentes protocolos de comunicación, exceptuando uno de los casos que no se
obtenía respuesta de su centralita electrónica. Se sospechó que posiblemente la
interface no funcionaba correctamente y se procedió a analizar con un
osciloscopio las señales que producía respecto al protocolo J1850PWM.
Para realizar las mediciones se tuvo recurrir a un osciloscopio digital con una
capacidad de muestro de hasta 1GHz, herramienta que aseguraba el visionado
más que correcto de la señal, ya que además esta era de tipo no periódica y por
tanto con un osciloscopio analógico es prácticamente imposible capturarla.
Resultado de la trama enviada a través del pin 2 (BUS+) del conector OBD-II
Resultado del trama enviada a través del pin 10 (BUS-) del conector OBD-II
29
Para entender el resultado de estas graficas es preciso hacer una descripción del
comportamiento de la capa física del protocolo j1850PWM. Este protocolo
dispone de dos líneas de comunicación, el BUS+ y BUS-, y se caracteriza por
utilizar la modulación del ancho de pulso (PWM) como mecanismo de
codificación de bits. El periodo de cada bit tiene una duración de 24 µs y su
estado se expresa de la siguiente forma:
Hecha esta explicación podemos darnos cuenta de que la gráfica que representa
el BUS+ desvela un pequeño problema eléctrico, ya que mientras que el BUS-
reacciona rápidamente colocándose a 0 V, el BUS+ nunca llega a lograr los 5 V,
quedándose siempre en los 4,4 V aproximadamente. Aunque este no sería un
problema para realizar la comunicación satisfactoriamente según las
especificaciones del protocolo SAEJ1850PWM, ya que se encuentra dentro de
los márgenes eléctricos permitidos, se procedió a modificar la electrónica que se
ocupa de implementar esta codificación.
30
En el esquema eléctrico observamos que los encargados de ajustar estas
tensiones son los Mosfets Q1 y Q2 (Q2 P-channel y Q1 N-channel) junto con las
resistencias R7 y R6. Partiendo de otro diseño disponible en la red que
implementa el mismo protocolo, se cambiaron los Mosfets por transistores PNP
y NPN (PNP->2N3906 y NPN->2N3904) y las resistencias R6 y R7 de 22kΩ por
resistencias de 2K7 Ω. Además se incorporaron resistencias de protección a las
bases de los transistores de 1KΩ.
31
Debido a que se constató que el problema no venia causado por el hardware se
empezó a investigar si podía venir dado por errores en las tramas enviadas.
Según el estándar J1850 PWM el formato de trama es el siguiente:
BIT 7 6 5 4 3 2 1 0
ID P P P H K Y Z Z
0 0 0 0 Prioridad máxima
0 0 1 1
0 1 0 2
0 1 1 3
1 0 0 4
1 0 1 5
1 1 0 6
1 1 1 7 Prioridad mínima
32
El bit 4 (H) indica si la cabecera es de 3 bytes o uno:
H=0 Tres bytes H=1 Un byte
33
El segundo byte representa a la dirección de memoria elegida que
identifica a la centralita (ECU).
34
En la siguiente captura podemos observar el fragmento de código donde se
encontraban estos datos, fue un tarea laboriosa ya que este fichero solo
contiene tramas hexadecimales, y es el resultado de la compilación de un
código fuente al que no se tenía acceso.
:103C70000350E66EE66A00010028BC6F000E0120CA
:103C8000BD6FBCC0E6FFBDC0E6FF040E0024BE6FE2
:103C9000000E0120BF6FBEC0E6FFBFC0E6FFDDEC37
:103CA0001EF046E90028E96E000E0120EA6E6A0E59
:103CB000EF6E020E0024E96E000E0120EA6E610E26
:103CC000EF6E030E0024E96E000E0120EA6EF10E85
:103CD000EF6E0001030EBC6F00EBE9FF01EBEAFFA2
:103CE000BC51EF2642E9E7CFD9FF1200D9CFE6FF5A
35
El estándar OBD-II contempla varios modos de trabajo, entre ellos el modo 01,
modo 03, modo 07, modo 04, modo 09, modo 22 y bastantes más. Cada uno de
ellos se ocupa de una parte de la información que puede aportar la ECU. El
modo más extendido entre todas las centralitas es el modo 01.
Cada modo además especifica sus parámetros PID (Parameter ID), en caso del
modo 01 uno puede ser el parámetro 00, que es el que se utiliza en nuestro
caso. Este parámetro sirve para decirle a la ECU que nos muestre cuales son los
PID que pueden ser utilizados en este modo de entre los PID que se encuentran
numerados del 1 al 20.
36
2.6 Diseño de la aplicación de prueba en C++
Hasta ahora se ha explicado el diseño utilizado para crear la parte de hardware de la
que se compone el proyecto, pero anteriormente se ha hecho referencia también a la
parte de software que es la que tiene más peso y elaboración. El desarrollo del
software se empezó a elaborar a partir del software libre ScanTool.net, que en una de
sus versiones ofrece el código fuente. Utilizando la herramienta Dev-C++ y este
código, el cual se basa en C++, se localizaron los métodos y funciones que se
sospechaban eran los responsables de mantener la comunicación mediante el puerto
serie. El primer paso fue averiguar cuál era la función que realizaba las operaciones
necesarias para realizar las comunicaciones con el PIC. Tras encontrarla y incorporarla
a un programa de prueba, se procedió a compilar la función, tras esto el mismo
compilador mencionaba cuales eran las funciones y variables que llamaba este
método para poder comunicarse, y por lo tanto poder buscarlas en el código anterior
para reunirlas en el programa de prueba. Una vez que se tenían todas las funciones y
variables en el mismo fichero se podía compilar el código sin obtener errores,
averiguando así cómo se comportaba el hilo de ejecución. Después de saber cuál era
la rutina de ejecución, se sacaron todas las órdenes o variables que no son
imprescindibles por realizar una comunicación básica, dejando la clase reducida al
máximo para tener una visión simple del proceso comunicación dejando a la vista
claramente las funciones necesarias. Finalmente el programa de prueba podía
realizar la comunicación enviando órdenes al PIC (atz, 0100, etc...) obteniendo los
mensajes enviados y los recibos con una visualización por consola. A continuación
aparece el código del programa de prueba:
37
38
Este programa utiliza la librería “allegro” como base, un librería muy utilizada
para desarrollar videojuegos, y por tanto era necesario indicarle al compilador
que la cargase con “-lalleg”, aunque también necesita cargar la librería
“iostream” y la “winalleg”, necesaria si se trabaja en Windows. Las funciones
implementadas son:
39
close_commport(): Cierra el puerto serie.
Como primer apunte se ha de decir que se utilizó el IDE para programar en Java
Eclipse. Para poder comunicarse con el puerto serie es necesario incluir las
librerías adecuadas en el paquete de la API de java instalada en el PC, es decir,
en el paquete autoinstalable “JDK-JRE” que ofrece gratuitamente Sun
Microsystems, ya que este no incluye librerías con esta funcionalidad.
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 Principal(){}
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);
}
}
} catch (IOException e) {
e.printStackTrace();
System.out.println(e);
}
}
42
Estructuralmente el programa se asemeja al diseño en C++, y por tanto
implementa métodos funcionalmente muy parecidos:
public static void main(): Método que inicia la ejecución del programa.
public void recibir(): Lee la trama de datos recibida del puerto serie.
Trama recibida del puerto serie atreves del método read() de la clase
SerialPort:
97,116,122,13,10,69,76,77,51,50,55,32,118,49,46,49,32,99,111,109,112,
97,116,105,98,108,101,13,10,62,-1
43
Comando a enviar: ”01 0C”-> equivalencia código ASCII:” 48,49,48,67”
Este comando sirve para pedirle a la centralita electrónica del vehículo
(ECU), a cuantas revoluciones por minuto (rpm), está girando el motor.
01 0C -> Respuesta
6A F1 61 41 0C 0B 88 0A Interface
Se puede observar que la interface le añade a la trama el comando
solicitado
Trama recibida del puerto serie atreves del método read() de la clase
SerialPort:
48,49,48,67,13,10,54,65,70,49,54,49,52,49,48,67,48,66,56,56,48,65,13,1
0,62,-1
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 conexión, etc..)
41 0C: Confirmación de que se ha contestado al comando requerido
sumando 40 a 01, quedando 41 0C.
0B 88: El dato que interesa para calcular las rpm. Según el documento
OBD Pid’s anteriormente mencionado, si pasamos a decimal estos
valores quedando en 11 y 136, y aplicamos esta fórmula
(( A ⋅ 256) + B ) = (11 ⋅ 256) + 136 = 738 , obtenemos las revoluciones por
4 4
minuto del motor a tiempo real.
0A: Chequeo de redundancia cíclica de la trama (CRC).
45
2.5. Diseño de la aplicación grafica diseñada en JAVA
El diseño final y definitivo de este proyecto consistía en realizar un software
multiplataforma diseñado mediante la conocida estructura de programación
“por capas”, para poder unir de forma correcta toda la capacidad de
comunicación que se había conseguido en los programas de prueba anteriores
con la necesidad de ofrecer muchas más opciones, entorno grafico y el potencial
que aporta un entorno visual diseñado con JAVA, lo cual dota al programa de
muchas posibilidades de configuración y operatibilidad sobre la interface y por
tanto sobre la centralita electrónica de cualquier vehículo.
Este software intenta ser compatible con cualquier plataforma que disponga de
una conexión USB o RS-232, de ahí su implementación mediante JAVA, pero
debido a que para realizar las comunicaciones con dichos puertos se ha utilizado
un librería nativa (RXTXcomm.jar), es posible que existan algunas
incompatibilidades de un plataforma a otra, cosa que se debería consultar en la
web de RXTXcomm.
47
Capa de Presentación: Esta capa se encarga de gestionar toda la parte
visual del programa y contiene todas las clases y controladores
necesarios para poder llevar a cabo esta tarea. Concretamente estas son
las clases que contiene:
ControladorPrincipal y VistaPrincipal: Gestionan la carga de todas las
demás clases de la capa de presentación y proporcionan las operaciones
básicas del programa, como son poder iniciar o detener un conexión con
la interface y seleccionar las diferentes opciones del programa.
ControladorErrores y VistaCodigosError: Estas clases se ocupan de
gestionar la presentación en pantalla de los códigos de error
proporcionados por la ECU.
ControladorMediciones y VistaMediciones: Se ocupan de gestionar la
presentación en pantalla de los datos referentes a valores que
proporcionan los sensores del vehículo, tales como temperatura,
velocidad, revoluciones por minuto, cantidad de aire absorbido, etc.…
ControladorProtocolo y VistaProtocolo: Gestionan la presentación en
pantalla de las opciones disponibles a la hora de seleccionar un
protocolo de comunicación.
ControladorPSerie y VistaConfiguración: Presentan en pantalla todas las
opciones que requiere el puerto serie para ser configurado. Además
permiten realizar una búsqueda de estos.
Por lo extenso del código de este último programa, se incorporará al final del
proyecto como documento adjunto.
tramaRecibidaInicial.append(z);
}
}
DestruirHilo=true;
} catch (IOException e1) {
estado("No response.");
}
Vemos que la línea subrayada, “datosRecibidos.read()”, es la orden que se
encarga de acceder al puerto y cuando el hilo de ejecución llega a ella en
Windows la lee una vez y sigue su transcurso dentro del método “run()” hasta el
siguiente ciclo de bucle donde lo volvería a leer, pero en Linux no sucede los
mismo, el hilo de ejecución se detiene en esta línea esperando un nuevo
mensaje del puerto y por tanto bloqueando su posible cierre desde el hilo
principal, es decir, como el hilo que se ejecuta en “run()” nunca libera al objeto
“port”, cuando accedemos al mismo objeto desde el hilo principal de la clase
este provoca un bloqueo de la aplicación ya que nunca tendrá permiso para
cerrarlo. Esto se solucionó enviando un mensaje cualquiera al puerto y
cambiando en el mismo instante la condición del bucle “while”(hilo=null), para
que el hilo de run() saliese de su estado de escucha y acabara extinguiéndose ya
que la condición del bucle ya no se cumplía.
49
Como aporte final a esta aplicación se procedió a empaquetarla en un archivo
“.jar”, lo que facilita mucho su puesta en marcha y portabilidad a cualquier otra
plataforma o sistema operativo. Pero uno de los inconvenientes que presentaba
esta aplicación era que para poder comunicarse con los puertos de
comunicación necesitaba la librería nativa “RXTXcomm”, y por tanto, esta no
viene incluida en las librerías de la maquina virtual que se instala por defecto, lo
que obliga a tener que instalarla manualmente.
50
Para poder realizar la carga de la librería nativa correctamente se tuvo que
modificar el archivo MANIFEST que contiene el paquete VisualOBD.jar
quedando de la siguiente forma:
51
3. Resultados
3.1. Ámbito de utilización
Este proyecto se basa en un sistema para el chequeo del estado técnico de
cualquiera de los vehículos que actualmente se comercializan o se han
comercializado desde 1996 en EEUU y 2001 en Europa, y por tanto su ámbito de
utilización se puede extender bastante, incluso como pequeña herramienta para
los profesionales del sector o para cualquier persona que disponga de un
vehículo dotado con el sistema On Board Diagnostics-II (OBD-II), que tenga
interés en indagar sobre el estado de su automóvil.
Esta herramienta podría ser muy útil, por ejemplo, para un pequeño taller
mecánico donde su presupuesto para adquirir un aparato de diagnostico es
reducido, y utilizando el sistema descrito aquí podría solucionarle muchos
problemas sin tener que hacer un gran desembolso económico.
También hay que decir que es necesario que el usuario tenga un mínimo de
conocimientos sobre la materia para comprender los resultados que muestra el
programa de diagnostico durante el chequeo del vehículo, lo que quizás hace
que se reduzca en parte el ámbito de uso.
52
Las pruebas realizadas se realizaron con éxito en los siguientes coches:
53
3.3. Descripción del funcionamiento
A continuación se describen los pasos a seguir para poner en marcha el sistema
a la hora hacer un chequeo sobre un vehículo. El primer paso es localizar en el
coche el conector OBD-II, ya que cada modelo lo puede incorporar en un lugar
diferente.
Una vez localizado debemos conectar nuestro cable OBD-II el cual proviene de
nuestra interface. Disponiendo de un ordenador portátil o de uno de sobremesa
cercano al lugar donde estemos trabajando, conectamos la interface al puerto
USB. El montaje sería el siguiente si se realiza en un Citroen C3 del año 2004, ya
que con respecto a otro modelo puede variar la localización del conector OBD-II.
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 serán utilizamos según en el sistema
operativo en que estemos trabajando.
En este caso arrancamos RunWindows.bat y nos aparecerá el siguiente entorno
visual:
55
El siguiente paso es realizar la conexión, y para ello debemos arrancar el motor
del coche, seleccionar los parámetros de configuración del puerto serie
(Options->Serial Port Configuration):
56
Ahora debemos seleccionar el protocolo de comunicación (Options-
>Communication protocol configuration). En el caso de no conocer el protocolo
que se va utilizar, el sistema lo detectará automáticamente:
57
El siguiente paso es iniciar la conexión cliqueando en “Connect”, si el proceso se ha
realizado con éxito obtendremos la siguiente respuesta:
58
En caso de que la conexión con la ECU sea fallida este sería el resultado:
Los demás comandos “AT”, son contestados correctamente porque son datos
procedentes únicamente de la interface, es decir, solo incumben a parámetros
que tienen que ver con el microcontrolador de la interface sin tener en cuenta a
la ECU.
59
Ahora podemos ver un ejemplo de la información que nos daría el programa en
el caso de que el vehículo tuviera almacenados 4 códigos de error indicando así
que se han producido estos fallos técnicos. Para acceder a esta información solo
hay que cliquear en “Read error codes”, estando por supuesto el sistema
correctamente conectado a la ECU:
60
Otra funcionalidad del programa es la lectura de datos a tiempo real de los
sensores que tiene instalados el motor. La cantidad de información que
podemos obtener, depende de la ECU, ya que según el modelo de esta, puede
ofrecer más o menos datos de los sensores que gestiona en la mecánica del
motor. Un ejemplo sería el siguiente:
61
En esta captura se observan más datos aportados por la ECU:
62
En esta otra imagen se observan las mismas lecturas pero realizadas a un
régimen de motor más alto, se ha pasado de estar en 751rpm a 1613.
63
Una imagen muy determinante para constatar que las lecturas son correctas es
la siguiente:
64
Hasta ahora el software se ha presentado funcionando bajo sistema operativo
Windows XP, pero también es capaz de funcionar en otros sistemas operativos,
como por ejemplo Linux. En la siguiente imagen podemos apreciarlo:
Respecto a Linux hay que hacer una pequeña aclaración sobre la detección de
los puertos serie. En este sistema operativo los puertos serie se suelen
identificar con nombres como “ttyS0”, “ttyACM0” o “ttyUSB0”, a diferencia de
los COM1, COM2, COM3, etc., de Windows y además se ubican en un carpeta
llamada “/dev”. Por tanto cuando arrancamos el programa en Linux
seleccionamos una de estas opciones y no tendremos ningún problema si
nuestra interface se conecta directamente al puerto RS-232, ya que la detectará
como /dev/ttySO, que es la referencia de dispositivo que siempre es detectada
de forma correcta.
65
Muchas de las interface compatibles utilizan el puerto USB, como es nuestro
caso, y en Windows las detecta también como puerto COM y no encontramos
problemas, pero en Linux estas interface son detectadas como /dev/ttyACM0, y
aquí es donde podemos tener impedimentos, porque este error viene causado
por la librería nativa RXTXcomm, la cual no contempla este tipo de puertos.
Para poder solucionarlo podemos ejecutar la siguiente línea de comando en un
terminal de Linux, con la intención de hacer un linkado simbólico de la interface
“/dev/ttyACM0” con una referencia que si reconozca la librería, por ejemplo
“/dev/ttyS0”:
Por tanto como ejemplo este sistema se puede aplicar en las labores de
manteniendo de cualquier profesional del sector que se encuentre con uno de
los vehículos mencionados anteriormente averiado y que después de su
reparación verifique con esta herramienta si el problema se ha subsanado
correctamente asegurándose de que la ECU no devuelve ningún código de error
o de que el sensor en cuestión ofrece unas lecturas correctas según
especificaciones del fabricante.
66
Otro ejemplo podría ser el que se da normalmente cuando cualquier poseedor
de un vehículo con OBD-II observa que en el cuadro de instrumentos se le ha
encendido una luz llamada “Check Engine” y se pregunta el porqué de este fallo.
En lugar de recurrir al servicio de mantenimiento inmediatamente podemos
proceder a realizar una lectura de “Codigos de Error” obteniendo el posible
código que nos describirá brevemente a que se debe el problema.
Otra de las facetas en las que se puede incluir este sistema es entre aquellas
personas que por puro placer o interés quieren conectarse con su automóvil
para observar los datos que la centralita electrónica les puede ofrecer, con fines
de simple curiosidad.
4. Comentarios finales
4.1 Plan de trabajo
El plan de trabajo de este proyecto se ha ido desarrollando según los siguientes
puntos:
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
68
D3 LED rojo 5mm
C1,C2,C4,C5 15pF
C3,C8,C9 0.1uF
C6 0.47uF
C10,C11 560pF
C7 10uF 16V
D3 LED Rojo 5 mm
C1, C4 33pF
C2 100µF 16V
C3 22µF 6.3V
R3 100Ω
R1 1.5KΩ
R2 10KΩ
69
Listado se software y hardware utilizado durante el proyecto:
4.3 Presupuesto
La tabla siguiente especifica el presupuesto detallado en euros:
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
continuación se detallan por puntos:
Lograr que el cable OBD-II utilizado previamente para hacer pruebas sea
fiable.
4.5 Conclusiones
El lenguaje de programación JAVA es una herramienta muy potente, ya
que permite que una misma aplicación pueda funcionar de igual forma
en diferentes sistemas operativos y plataformas.
72
Bibliografía
[1] OBD2 ELM327 compatible AllPro adapter with USB, www.obddiag.net
73
Anexo
Código ejemplo para el manejo de la librería “RXTXcomm” en lenguaje Java,
disponible en www.rxtx.org:
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
}
else
{
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}
74
public static class SerialReader implements Runnable
{
InputStream in;
75
Código fuente del software de control desarrollado en el proyecto:
Capa de Datos:
Clase Conexión:
package Datos;
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 ControladorConexión:
package Datos;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.JTextArea;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
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;
}
estado("Connected "+con.getNombrePuerto()+".");
enviar("atz");
enviar(con.getProtocolo());
enviar("0100");
enviar("atdp");
enviar("atdpn");
enviar("ath1");
enviar("0100");
timer();
}
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.");
}
}
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;
}
}
}
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.";
}
}
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);
}
}
}
}
84
public void asignaIDCanBus(){
ID=MIDs.getJListIDs().getSelectedValue().toString();
}
Clase lecturaTXTErrores:
package Datos;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
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
//código 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 MuestraIDs() {
super();
initialize();
}
Capa de Dominio:
Clase ControladorDominioConexión:
package Dominio;
import java.util.Vector;
import javax.swing.JTextArea;
import Datos.Conexion;
import Datos.ControladorConexion;
89
public String cojer_pids(){
return contCon.cojer_pids();
}
public String devuelvePid(){
return contCon.devuelve_pid();
}
Capa de Presentación:
Clase ConfirmaciónBorradoErrores:
package Presentacion;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Rectangle;
import javax.swing.JButton;
public 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;
}
}
return jButtonOK;
}
}
return jButtonCancel;
}
91
Clase ControladorErrores:
package Presentacion;
import javax.swing.JPanel;
import Dominio.ControladorDominioConexion;
VistaCodigosError VCE;
ControladorDominioConexion contDom;
ControladorMediciones contMed;
ConfirmacionBorradoErrores confErr;
boolean ventanaConfirmaErrores;
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.
}
}
});
}
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;
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;
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");
}
}
});
}
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;
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();
}
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();
}
});
}
Clase ControladorProtocolo:
package Presentacion;
import javax.swing.JPanel;
import Dominio.ControladorDominioConexion;
110
public class ControladorProtocolo {
VistaProtocolo VProt;
String protocolo;
ControladorDominioConexion contDom;
return protocolo;
}
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;
VistaConfiguracio VC;
Conexion con;
ControladorDominioConexion contDom;
public ControladorPSerie(ControladorDominioConexion contDom){
VC = new VistaConfiguracio();
this.contDom = contDom;
eventos();
datosconexion();
}
}
});
}
}
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 VistaCodigosError() {
super();
initialize();
}
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 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);
}
116
public JComboBox getJComboBoxStopBits() {
if (jComboBoxStopBits == null) {
jComboBoxStopBits = new JComboBox(bitsParada);
jComboBoxStopBits.setBounds(new Rectangle(30, 330, 135, 25));
jComboBoxStopBits.setSelectedIndex(0);
}
return jComboBoxStopBits;
}
}
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;
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();
}
120
jTabbedPane.addTab(" PID's 21-40 ", null,
getJPanel21_40(), null);
jTabbedPane.addTab(" PID's 41-60 ", null,
getJPanel41_60(), null);
}
return jTabbedPane;
}
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;
}
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;
}
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;
}
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;
}
130
jTextField10.setEditable(false);
jTextField10.setBackground(Color.white);
}
return jTextField10;
}
131
return jTextField16;
}
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;
}
133
jTextField27.setHorizontalAlignment(JTextField.CENTER);
jTextField27.setFont(new Font("Dialog", Font.BOLD, 22));
jTextField27.setEditable(false);
jTextField27.setBackground(Color.white);
}
return jTextField27;
}
134
jTextField2C.setBackground(Color.white);
}
return jTextField2C;
}
135
}
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;
}
137
jTextField3F.setHorizontalAlignment(JTextField.CENTER);
jTextField3F.setFont(new Font("Dialog", Font.BOLD, 22));
jTextField3F.setEditable(false);
jTextField3F.setBackground(Color.white);
}
return jTextField3F;
}
138
jTextField3D.setBackground(Color.white);
}
return jTextField3D;
}
}
return jButtonLeer;
}
}
return jButtonDetener;
}
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;
}
140
jTextField4A.setFont(new Font("Dialog", Font.BOLD, 22));
jTextField4A.setEditable(false);
jTextField4A.setBackground(Color.white);
}
return jTextField4A;
}
141
}
return jTextField51;
}
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;
142
private JButton jButtonDesconectar = null;
public VistaPrincipal() {
super();
this.setLocation(new Point(100, 25));
initialize();
}
143
jMenuInicio.add(getJMenuItemLectura());
jMenuInicio.add(getJMenuItemExit());
}
return jMenuInicio;
}
}
return jButtonConectar;
}
}
return jButtonDesconectar;
}
144
private JMenu getJMenuOpciones() {
if (jMenuOpciones == null) {
jMenuOpciones = new JMenu();
jMenuOpciones.setText(" Options ");
jMenuOpciones.add(getJMenuItemPSerie());
jMenuOpciones.add(getJMenuItemProtocolo());
}
return jMenuOpciones;
}
}
return jMenuItemPSerie;
}
}
return jMenuItemProtocolo;
}
145
}
return jTextFieldEnvioManual;
}
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 VistaProtocolo() {
super();
initialize();
}
147
grupoBotones.add(getJRadioButtonKWP1());
grupoBotones.add(getJRadioButtonKWP2());
grupoBotones.add(getJRadioButtonCAN1());
grupoBotones.add(getJRadioButtonCAN2());
grupoBotones.add(getJRadioButtonCAN3());
grupoBotones.add(getJRadioButtonCAN4());
getJRadioButtonAutomatico().setSelected(true);
}
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;
}
149
if (jComboBoxRec1 == null) {
jComboBoxRec1 = new JComboBox(hexa);
jComboBoxRec1.setBounds(new Rectangle(575, 135, 40, 20));
}
return jComboBoxRec1;
}
150