Telemetria Automotiva via Internet Móvel

Transcrição

Telemetria Automotiva via Internet Móvel
Universidade de Brasília
Instituto de Ciências Exatas
Departamento de Ciência da Computação
Telemetria Automotiva via Internet Móvel
Alcides Carlos de Moraes Neto
Brasília
2009
Universidade de Brasília
Instituto de Ciências Exatas
Departamento de Ciência da Computação
Telemetria Automotiva via Internet Móvel
Alcides Carlos de Moraes Neto
Monografia apresentada como requisito parcial
para conclusão do Bacharelado em Ciência da Computação
Orientador
Prof. Ricardo Pezzuol Jacobi
Brasília
2009
Universidade de Brasília — UnB
Instituto de Ciências Exatas
Departamento de Ciência da Computação
Bacharelado em Ciência da Computação
Coordenador: Prof.a Carla Maria Chagas e Cavalcante Koike
Banca examinadora composta por:
Prof. Ricardo Pezzuol Jacobi (Orientador) — CIC/UnB
Prof. Pedro de Azevedo Berger — CIC/UnB
Prof.a Carla Maria Chagas e Cavalcante Koike — CIC/UnB
CIP — Catalogação Internacional na Publicação
de Moraes Neto, Alcides Carlos.
Telemetria Automotiva via Internet Móvel / Alcides Carlos de Moraes Neto. Brasília : UnB, 2009.
111 p. : il. ; 29,5 cm.
Monografia (Graduação) — Universidade de Brasília, Brasília,
2009.
1. Sistema embarcado, 2. Sistema automotivo, 3. Telemetria,
4. Internet móvel
CDU 004.7
Endereço:
Universidade de Brasília
Campus Universitário Darcy Ribeiro — Asa Norte
CEP 70910-900
Brasília–DF — Brasil
Universidade de Brasília
Instituto de Ciências Exatas
Departamento de Ciência da Computação
Telemetria Automotiva via Internet Móvel
Alcides Carlos de Moraes Neto
Monografia apresentada como requisito parcial
para conclusão do Bacharelado em Ciência da Computação
Prof. Ricardo Pezzuol Jacobi (Orientador)
CIC/UnB
Prof. Pedro de Azevedo Berger
CIC/UnB
Prof.a Carla Maria Chagas e Cavalcante Koike
CIC/UnB
Prof.a Carla Maria Chagas e Cavalcante Koike
Coordenador do Bacharelado em Ciência da Computação
Brasília, 7 de dezembro de 2009
À Alda, querida avó.
Agradecimentos
Agradeço primeiramente ao meu orientador, prof. Ricardo Jacobi por liderar este
excelente projeto de pesquisa, me dando a oportunidade de realizar este trabalho
que tanto me motivou e satisfez.
A toda a equipe envolvida, tanto da UnB quanto da SEA Tecnologia, pelo ambiente de colaboração e discussão, sem o qual este trabalho não seria o mesmo.
A todos os professores com quem tive contato durante esta longa jornada pela
UnB. Aprendi com todos, não só conteúdo mas como ser uma pessoa melhor. Em
especial, aos professores Marcelo Ladeira, Marco Aurélio e Alba Cristina por terem
me tirado o medo de aprender C e pelas aulas engrandecedoras.
Aos meus colegas de curso, novos e velhos, com os quais também aprendi muito.
Ao pessoal do DAA e do DAIA na reitoria, por terem me dado a chance de concluir meu curso. Em especial ao Edson do posto avançado do DAA, por aguentar os
telefonemas e sempre fazer o possível para ajudar.
Aos meus amigos pelos momentos de diversão e descontração, sem os quais não
seria possível manter a sanidade. Vocês me deram bônus no meu will save, IZO!
Aos meus pais, minhas irmãs, meu avô xará, e toda minha família, pelo apoio,
tanto material quanto motivacional, e paciência durante toda esta jornada. Muito
obrigado.
A minha linda e amada mulher, Ludmila Araujo. Foi com sua inteligência e
sensibilidade que consegui ser o melhor que eu posso, e que tornou este trabalho
possível. Muito obrigado, por tudo. Te amo mais que tudo na vida.
v
Resumo
O presente trabalho tem como objetivo estudar a implementação de um sistema
embarcado para a telemetria de um automóvel via internet móvel para o projeto
Karmonitor. São levantadas as tecnologias disponíveis para monitoramento e diagnóstico em um automóvel, como o padrão OBD (On-board Diagnostics) e os protocolos mais usados para comunicação das diversas unidades eletrônicas de controle (ECUs) presentes no automóvel, como o CAN (Controller Area Network) e o
J1850. São também estudadas as tecnologias móveis de conexão à Internet que
estão disponíveis hoje e que deverão ser usadas pelo sistema embarcado. É abordado também o ambiente que foi definido pelo projeto Karmonitor onde o sistema
será implementado, os softwares disponíveis para apoio e o desenvolvimento dos
programas necessários para a execução da telemetria. Testes são feitos em alguns
diferentes modelos de carros para averiguar o comportamento do sistema
Palavras-chave: Sistema embarcado, Sistema automotivo, Telemetria, Internet
móvel
vi
Abstract
This work aims to study the implementation of an embedded automotive telemetry
system via mobile Internet services for the Karmonitor project. Research is made
on the available technologies for automotive diagnoses, like the OBD (On-board
Diagnostics) standard and the most used bus protocols for communications of the
many ECUs (Electronic Control Units) inside a car’s system, like CAN (Controller
Area Network) and J1850. Also study is made on mobile Internet connection technologies that are available today that can be used in this embedded system. All this
will be done before analysing the environment defined for the Karmonitor system,
the software available that can support a telemetry system and the development
of programs needed to execute it. Tests are made on some car models in order to
observe the system’s behaviour.
Keywords: Embedded system, Automotive system, Telemetry, Mobile Internet
vii
Lista de Figuras
1.1 Exemplo de arquitetura para telemetria via Internet . . . . . . . . .
1.2 Diagrama de arquitetura de telemetria móvel . . . . . . . . . . . . . .
2.1
2.2
2.3
2.4
Diagrama de um automóvel com 3 redes distintas:
Quadro de dados do protocolo CAN 2.0A . . . . . .
Quadro de dados do protocolo CAN 2.0B . . . . . .
Ciclo de comunicação do protocolo FlexRay . . . .
4
5
LIN, CAN e MOST 7
. . . . . . . . . . . 15
. . . . . . . . . . . 15
. . . . . . . . . . . 18
3.1 Esquema do conector OBD-II . . . . . . . . . . . . . . . . . . . . . . .
3.2 Interface OBD x USB de Alex Sidorenko . . . . . . . . . . . . . . . . .
3.3 Esquema elétrico da interface OBD x USB de Alex Sidorenko . . . .
22
23
24
4.1 Uma rede GSM com nós SMS e GPRS (Junior, 2005) . . . . . . . . .
4.2 Placa PCMCIA da VIVO para acesso a rede GSM 3G . . . . . . . . .
4.3 Interface USB GSM 3G. . . . . . . . . . . . . . . . . . . . . . . . . . .
30
31
32
5.1
5.2
5.3
5.4
A Beagle Board com seus principais componentes destacados .
Fluxograma do programa cliente . . . . . . . . . . . . . . . . .
Fluxograma do programa servidor . . . . . . . . . . . . . . . .
Diagrama de classes do programa servidor . . . . . . . . . . .
.
.
.
.
.
.
.
.
34
37
39
40
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
6.10
Exemplo de arquivo de configuração do cliente . . . . . . . . . . . .
Notebook Dell utilizado para executar o sistema . . . . . . . . . . .
Conector USBxOBD . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Celular Nokia N95 com cabo USB para uso como modem 3G/GPRS.
Automóvel Ford Ka 1.0, ano 2009, exterior. . . . . . . . . . . . . . .
Localização do conector OBD no Ford Ka. . . . . . . . . . . . . . . .
Automóvel Nissan Livina 1.6, ano 2009, exterior. . . . . . . . . . . .
Localização do conector OBD no Nissan Livina. . . . . . . . . . . . .
Automóvel Ford Focus 2.0, ano 2009, exterior. . . . . . . . . . . . . .
Localização do conector OBD no Ford Focus. . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
45
53
53
54
54
55
55
56
56
57
viii
.
.
.
.
.
.
.
.
Lista de Tabelas
2.1 Tipos de protocolo J1850 (Riley, 1998) . . . . . . . . . . . . . . . . . .
2.2 Símbolos do protocolo J1850 (Riley, 1998) . . . . . . . . . . . . . . . .
8
9
3.1 Dados OBD-II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
5.1 Estrutura da tabela de veículos . . . . . . . . . . . . . . . . . . . . . .
5.2 Estrutura parcial da tabela de dados OBD . . . . . . . . . . . . . . . .
5.3 Comandos que o servidor pode enviar ao cliente . . . . . . . . . . . .
41
41
42
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
6.10
6.11
6.12
47
48
48
49
49
50
50
51
51
51
52
52
Dados OBD suportados pelo Ford Ka. . . . . . . . . . . . . . . .
Taxas do sistema observadas durante testes no Ford Ka. . . . .
Exemplo de dados levantados para o Ford Ka. . . . . . . . . . .
Valores médios de parâmetros levantados para o Ford Ka. . . .
Dados OBD suportados pelo Nissan Livina. . . . . . . . . . . . .
Taxas do sistema observadas durante testes no Nissan Livina. .
Exemplo de dados levantados para o Nissan Livina. . . . . . . .
Valores médios de parâmetros levantados para o Nissan Livina.
Dados OBD suportados pelo Ford Focus. . . . . . . . . . . . . . .
Taxas do sistema observadas durante testes no Ford Focus. . . .
Exemplo de dados levantados para o Ford Focus. . . . . . . . . .
Valores médios de parâmetros levantados para o Ford Focus. . .
ix
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Sumário
Lista de Figuras
viii
Lista de Tabelas
ix
1 Introdução
1.1 Projeto Karmonitor . . . . . .
1.2 Problema . . . . . . . . . . . .
1.3 Objetivos . . . . . . . . . . . .
1.4 Motivação . . . . . . . . . . . .
1.5 Metodologia . . . . . . . . . .
1.6 Telemetria . . . . . . . . . . .
1.6.1 Análise da arquitetura
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2 Tecnologias de barramento automotivas
2.1 Classe A . . . . . . . . . . . . . . . . . .
2.1.1 Local Interconnect Network . . .
2.1.2 TTP/A . . . . . . . . . . . . . . . .
2.2 Classe B . . . . . . . . . . . . . . . . . .
2.2.1 J1850 . . . . . . . . . . . . . . . .
2.2.2 ISO 9141-2 . . . . . . . . . . . . .
2.2.3 ISO 14230-4 . . . . . . . . . . . .
2.2.4 Low-speed CAN . . . . . . . . . .
2.3 Classe C . . . . . . . . . . . . . . . . . .
2.3.1 High-speed CAN . . . . . . . . . .
2.3.2 TTP/C . . . . . . . . . . . . . . . .
2.4 Classe D . . . . . . . . . . . . . . . . . .
2.4.1 MOST . . . . . . . . . . . . . . . .
2.4.2 FlexRay . . . . . . . . . . . . . . .
3 Aquisição de dados
3.1 OBD . . . . . . . . . . . . . . . . . . .
3.1.1 História . . . . . . . . . . . . .
3.1.2 Padrões OBDBr-1 e OBDBr-2
3.1.3 Padrão OBD-II . . . . . . . . .
x
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
2
2
3
3
3
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
7
7
8
8
8
10
12
12
16
16
17
17
17
17
.
.
.
.
19
19
19
20
21
4 Telefonia móvel
4.1 GSM . . . . . . . . . . . . . . . .
4.1.1 SMS . . . . . . . . . . . .
4.1.2 GPRS . . . . . . . . . . .
4.1.3 EDGE e UMTS . . . . .
4.1.4 Acesso à Internet Móvel
.
.
.
.
.
5 Arquitetura do Sistema
5.1 Hardware . . . . . . . . . . . . . .
5.2 Sistema Operacional . . . . . . .
5.2.1 Linux . . . . . . . . . . . .
5.2.2 Angstrom . . . . . . . . . .
5.3 Software . . . . . . . . . . . . . .
5.3.1 Medição . . . . . . . . . . .
5.3.2 Cliente . . . . . . . . . . .
5.3.3 Servidor . . . . . . . . . .
5.3.4 Protocolo de comunicação
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
28
28
29
29
30
31
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
33
33
34
35
35
35
36
38
42
6 Testes e análises
6.1 Plataforma de testes . . . . . . . . . . .
6.2 Procedimentos . . . . . . . . . . . . . . .
6.2.1 Montagem do ambiente cliente .
6.2.2 Montagem do ambiente servidor
6.3 Cálculos . . . . . . . . . . . . . . . . . . .
6.4 Ford Ka 1.0 2009 . . . . . . . . . . . . .
6.4.1 Dados do teste . . . . . . . . . . .
6.4.2 Campos OBD suportados . . . . .
6.4.3 Valores observados . . . . . . . .
6.5 Nissan Livina 1.6 2009 . . . . . . . . . .
6.5.1 Dados do teste . . . . . . . . . . .
6.5.2 Campos OBD suportados . . . . .
6.5.3 Valores observados . . . . . . . .
6.6 Ford Focus 2.0 2009 . . . . . . . . . . . .
6.6.1 Dados do teste . . . . . . . . . . .
6.6.2 Campos OBD suportados . . . . .
6.6.3 Valores observados . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
43
43
44
44
45
46
47
47
47
48
48
48
49
49
50
50
50
51
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7 Conclusão e desenvolvimentos futuros
58
Referências
60
I
Código-fonte do cliente
I.1 clientmain.h . . . . .
I.2 clientmain.c . . . . .
I.3 database.h . . . . . .
I.4 database.c . . . . . .
I.5 networking.h . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
xi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
63
63
64
70
71
73
I.6
networking.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
II Código-fonte do servidor
II.1 Main.java . . . . . . . .
II.2 ServerThread.java . . .
II.3 DbConnector.java . . .
II.4 ObdDao.java . . . . . .
II.5 Vehicle.java . . . . . . .
II.6 VehicleDao.java . . . .
75
.
.
.
.
.
.
79
79
81
87
89
91
93
III Tabelas do banco de dados do servidor
III.1 Tabela VEHICLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
III.2 Tabela OBDGPSDATA . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
95
95
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
xii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Capítulo 1
Introdução
Desde o início dos anos 70, cada vez mais os veículos automotores têm sido equipados com unidades eletrônicas de controle (Electronic Control Units - ECU). Estas
ECUs realizam monitoramentos, compartilham informações através de barramentos, fazem ajustes baseados nas informações disponíveis e muitas já são responsáveis por funções vitais para o funcionamento dos veículos (por ex: injeção eletrônica).
É fácil ver o porquê desta tendência: Equipamentos eletrônicos oferecem muito
mais versatilidade, confiabilidade e performance do que máquinas estritamente
mecânicas. As possibilidades que são disponibilizadas pela tecnologia de software
permite a implantação de sistemas complexos que melhoram não só o desempenho
do veículo, mas como a segurança e o conforto de seu usuário.
1.1
Projeto Karmonitor
O projeto Karmonitor propõe o desenvolvimento de uma plataforma em sistema
embarcado para telemonitoramento e telecontrole de veículos baseada em FPGA.
Um dos objetivos do projeto é permitir que o usuário obtenha informações sobre
o estado do veículo e envie comandos para alterá-lo através de aplicação executando
em telefone celular. Atualmente os serviços de telefonia celular apresentam uma
área de cobertura significativa. Associada a larga difusão dos aparelhos celulares na sociedade, a possibilidade de acessar informações sobre o estado do veículo,
incluindo sua localização, e enviar comandos para controlá-lo através do celular
caracteriza um nicho de mercado ainda não explorado, e uma oportunidade para
desenvolvimento de um produto inovador e com forte apelo comercial.
Outro objetivo do projeto é ser um interpretador de comandos vocais emitidos
tanto por celular como do interior do veículo. O controle do estado do veículo através de uma interface natural, além de auxiliar o usuário comum, é igualmente de
interesse para portadores de necessidades especiais (PNE), pois permite ao motorista realizar tarefas sem a necessidade de retirar as mãos do volante.
1
1.2
Problema
Um dos problemas que o projeto Karmonitor aborda é o da medição de dados funcionais de veículos remotamente, de forma automatizada, que será o foco deste
projeto.
Os veículos automotivos devem ser submetidos a constantes revisões para averiguação do seu funcionamento e performance. Este processo está cada vez mais
informatizado, como pode ser visto neste projeto, com o desenvolvimento de protocolos para medição dos dados funcionais do veículo, diminuindo a necessidade de
diagnóstico mecânico. Mas ainda assim é necessário que o veículo seja retirado
de circulação e seja submetido a técnicos humanos que, mesmo com a crescente
informatização do processo, ainda podem cometer erros.
Como essas medições são periódicas, e dependem que o proprietário do veículo
leve-o até a assistência técnica, nem elas são realizadas pelos veículos estarem
funcionando satisfatoriamente, apesar de estarem desregulados. Uma das consequências disso é um maior consumo de combustível pelos veículos desregulados,
e também maior quantidade de poluentes gerados.
Apesar de existir legislação que estabeleça limites para a emissão de poluentes
pelos veículos (Lei 8.723, de 28 de outubro de 1993), ela é praticamente nula, visto
que não existe forma fácil para medição deste parâmetro em larga escala.
1.3
Objetivos
A proposta deste projeto para a solução do problema é um sistema embarcado a
bordo do veículo para aquisição e envio dos dados para uma aplicação servidora via
Internet, utilizando uma conexão via rede celular.
Este sistema de telemetria levantaria periodicamente os dados disponibilizados
pelo automóvel e enviar-los-ia a um ou mais destinatários, que podem ser máquinas servidoras dedicadas a receber e processar estes dados ou mesmo o celular do
proprietário.
Objetivos específicos:
1. Estudo das tecnologias:
(a) Redes digitais intraveiculares e como criar uma interface com elas.
(b) Redes celulares e como realizar conexão com a Internet através delas.
2. Desenvolvimento da aplicação:
(a) Módulo para aquisição dos dados de um veículo.
(b) Módulo para envio dos dados pela Internet, utilizando rede celular.
(c) Programa servidor que fará o recebimento e processamento dos dados.
2
1.4
Motivação
Um sistema que possibilite monitoramento remoto de automóveis pode ser aplicado
para diversos fins, inclusive:
• No monitoramento de frota de veículos de uma empresa ou entidade, diminuindo o número de vezes que o veículo deve ser retirado de circulação para
manutenção.
• Em estudo estatístico por parte da montadora ao utilizar o sistema em todos
seus veículos, obtendo assim uma população muito significativa para estudo.
• Na verificação do nível de emissão de gases poluentes dos automóveis, possibilitando assim a fiscalização da legislação vigente, melhorando a qualidade
do ar e diminuindo o consumo de combustível fóssil.
1.5
Metodologia
Para chegar a tais objetivos, pode-se destacar os principais passos:
1. Arquitetura do sistema e ambiente de desenvolvimento: É necessário antes
de mais nada conhecer o ambiente de desenvolvimento utilizado e qual será
sua arquitetura.
2. Aquisição de dados: É necessário que o sistema consiga acessar os dados funcionais do automóvel. É necessário que seja definido o hardware e/ou software
necessário.
3. Processamento dos dados: Depois de recuperar os dados, o sistema deverá
tratá-los e decidir o envio deles. Aqui pode ser feita seleção de qual servidores receberão os dados. Por exemplo pode haver um destino para dados de
funcionamento e outro para dados de problema ou defeitos.
4. Envio dos dados: Estudar a tecnologia que será usada para o envio, considerando a possibilidade de múltiplos protocolos se for possível e plausível. Por
exemplo, dados ao condutor ou proprietário do veículo podem ser feitos via
SMS. Dados para um servidor na Internet podem ser enviados por GPRS.
5. Arquitetura de um sistema servidor: Levantar as possibilidades para o recebimento destes dados via Internet: Qual o tipo de protocolo e software usar
para receber esses dados. Também as estatísticas que podem ser levantadas
por um servidor.
1.6
Telemetria
Telemetria é uma forma de tecnologia muito empregada em diversas áreas da ciência, com a medicina (Gutierrez, 2006; Paim, 2005) a biologia (Mantovani and
3
Figura 1.1: Arquitetura para telemetria via Internet proposta em Khan et al.
(2007).
Santos, 2001), e até mesmos parques temáticos (Walker, 2007). Consiste na medição de dados de interesse de um analisador e consequente envio desses dados para
um acumulador para posterior análise.
Tais sistemas diferem entre si tanto pela tecnologia empregada quanto pela
arquitetura adequada para resolver suas necessidades. Normalmente são implantados em locais de difícil acesso, as vezes inóspitos a seres humanos, possibilitando
o monitoramento constante destes sistemas em outro local, possuindo diferentes
necessidades de distância e banda de transmissão.
Considerando o local de instalação do projeto, um automóvel, e o ambiente urbano em que circula, foi escolhido hardware e interface de comunicação adequados
para prover acesso a um acumulador remoto: Acesso à Internet via rede celular,
presente na grande maioria de cidades brasileiras. Pela Internet então, é possível
acessar um servidor em qualquer lugar do mundo, que servirá de acumulador de
dados.
1.6.1
Análise da arquitetura
Sistemas de Telemetria via Internet já existem, como visto em Khan et al. (2007),
porém, a arquitetura proposta sugere a conexão remota do medidor ao dispositivo sendo medido, configurando uma arquitetura cliente-servidor onde o servidor
é quem faz o levantamento dos dados. Esta arquitetura pode ser visualizada na
figura 1.1.
Analisando esta arquitetura para uma aplicação automotiva, ela não parece a
ideal, pelas seguintes razões:
• Uma conexão móvel não tem endereçamento estável. Ao movimentar-se, um
dispositivo celular troca a central de comunicações com a qual mantém conexão constantemente, mudando assim seu endereçamento. Um endereçamento
dinâmico dificulta a conexão remota.
4
Figura 1.2: Diagrama da arquitetura de telemetria móvel proposta em Jenkins
(2004).
• Conexões móveis são instáveis, podendo ser perdidas em uma troca de central
ou mesmo quando o veículo está fora da área de cobertura.
Esta arquitetura é plausível para sistemas que têm uma conexão estável e constante com a Internet, o que não é o caso.
Uma arquitetura para medição de performance de veículos via Internet é proposta em Jenkins (2004). A arquitetura proposta considera estas dificuldades e estabelece um fluxo contrário, onde a máquina cliente está no veículo, enquanto um
servidor remoto recebe os dados enviados pelo veículo constantemente e o armazena em um banco de dados. Máquinas clientes então se conectam a este servidor
intermediário para fazer consultas. Um diagrama desta arquitetura pode ser visto
na figura 1.2.
A arquitetura do sistema será baseada nesta, muito mais plausível em um ambiente automotivo. A medição constante pelo sistema será armazenada localmente
antes de acontecer a tentativa de envio, evitando com que dados sejam perdidos.
5
Capítulo 2
Tecnologias de barramento
automotivas
Com o crescente número e complexidade de ECUs nos veículos, tornou-se necessário que estes componentes trocassem informações entre si. A princípio a comunicação era feita através de ligações diretas entre os componentes. Mas o crescente
número destas ECUs tornou esta solução ineficaz, visto que para cada n controladoras, seria necessário n2 conexões para interligar todos. Dada esta situação, a
possibilidade de se conectar um número arbitrário de componentes entre si, com
protocolo de comunicação pré-definido por uma interface padrão foi o motivador
para a criação dos barramentos automotivos.
Estudar a tecnologia utilizada no automóvel para transmissão de dados entre os
ECUs é fundamental para a arquitetura de um sistema embarcado, pois é através
dela que será feita a troca de mensagens entre os componentes do carro e o sistema.
Para entender melhor os requisitos do automóvel, suas funções são separadas
em domínios (Navet et al., 2005) que correspondem a diferentes recursos e restrições. Estes domínios são:
1. Sistema de força: Responsável pelo controle do motor e transmissão.
2. Chassi: Onde é feito o controle de suspensão, volante e freios.
3. Corpo: Recursos de conforto como inclinação de assento e ar condicionado.
4. Telecomunicação: Comunicações com o mundo externo; sem-fio, sistemas de
localização.
5. Multimídia e Interface homem máquina (HMI): Interação com o condutor e
passageiros.
6. Segurança: Voltado para a segurança dos ocupantes do veículo.
Existem diversas tecnologias usadas para a comunicação dos componentes, cada
qual com características específicas para atender os diferentes domínios (como
tempo de resposta, banda, redundância, detecção de erros, etc.), e é normal encontrar mais de um barramento implantado em um veículo (Podemos ver um exemplo
de implementação na figura 2.1). Em 1994, a Sociedade de Engenheiros Automotivos dos Estados Unidos (SAE - Society for Automotive Engineers) definiu uma
6
classificação para protocolos de comunicação automotivos baseada na velocidade
de transmissão de dados e funções que são distribuídas pela rede. Os protocolos
foram separados em classes A, B, C e D (Leen and Heffernan, 2002; Leen et al.,
1999).
Figura 2.1: Diagrama de um automóvel com 3 redes distintas: LIN, CAN e MOST
2.1
Classe A
São redes com taxa de transmissão menor que 10kb/s, usadas para transmitir dados de controle simples, utilizando tecnologias de baixo custo. São principalmente
utilizadas no domínio "‘corpo"’, que possui somente sistemas não críticos como controle de assento e detector de chuva. Exemplos de redes classe A são LIN e TTP/A.
2.1.1
Local Interconnect Network
LIN, ou Local Interconnect Network, é uma evolução do ISO 9141, uma rede de
baixa velocidade e custo. Esta rede é normalmente usada para interligar dispositivos simples sem muitas variáveis de controle como assentos, espelhos e janelas.
Sua arquitetura é a mestre-escravo que, além de não necessitar de diversos nodos
com funcionamento complexo, é também uma medida de segurança, visto que é
impossível comprometer outros nodos da rede através de um nodo vulnerável. (Por
exemplo, abrir a janela do carro através do sistema de controle dos vidros retrovisores) (Leen and Heffernan, 2002).
É um padrão aberto (criado pelas empresas Audi, BMW, DaimlerChrysler, Motorola, Volcano, Volvo e Volkswagen) e foi desenvolvido com o intuito de ser integrado
com protocolos de maior velocidade como o CAN.
7
2.1.2
TTP/A
Protocolo similar ao LIN, mas de iniciativa acadêmica, criado pela Universidade
Técnica de Vienna, Áustria; Universidade Técnica de Munich e Universidade de
Stuttgart, Alemanha. Assim como o LIN foi criado para complementar o CAN, o
TTP/A foi criado para complementar o TTP/C, de autoria também das faculdades
citadas (Kopetz and Grunstidl, 1993).
TTP significa Time Triggered Protocol, devido a sua principal característica
que é a estratégia de envio de dados em janelas de tempo específicas para cada
nodo (TTA Group, 2004).
Os dois protocolos são semelhantes, mas o TTP/A foi desenvolvido com maior
número de aplicações em mente, não somente a automobilística. Comparações
entre o TTP/A e o LIN mostram a superioridade do TTP/A quanto a recursos e
performance (Kopetz et al., 2000).
2.2
Classe B
Redes dedicadas à conexão de ECUs, de forma a diminuir a necessidade de sensores
através da troca de informações. Estas redes operam entre 10 e 125 kb/s. O J1850 e
o CAN de baixa velocidade (low-speed CAN) são os principais representantes desta
classe.
São protocolos desta classe que são usados para diagnóstico a bordo (OBD).
2.2.1
J1850
O barramento J1850, adotado pela SAE em 1994 como o padrão classe B mas já
considerado em declínio em favor do CAN, é um barramento usado em aplicações
de diagnóstico e compartilhamento de dados em veículos.
A GM e a Chrysler adotaram J1850 VPW, denominando-o de Barramento Classe
2 (Class 2 Bus). A Ford utiliza o J1850 PWM, que é definido como o Protocolo
Corporativo Padrão (Standard Corporate Protocol).
Características
O J1850 é usado de duas formas: A 41.6 Kbps via modulação por largura de pulso
(PWM) em cabo duplo, ou a 10.4 Kbps via modulação de pulso variável (VPW) em
cabo simples. Apesar de não serem compatíveis na camada física, os dois tipos possuem semelhanças na camada de ligação de dados. O protocolo utiliza a estratégia
de transmissão CSMA/NDA (Oliver, 2001). A tabela 2.1 mostra as características
dos dois tipos.
Rede
Taxa Transm.
Int. Física
J1850 VPW
10.4 kbits/s
Fio simples (com terra)
J1850 PWM
41.6 kbits/s
Dois fios, sinal balanceado
Tabela 2.1: Tipos de protocolo J1850 (Riley, 1998)
8
O padrão J1850 define um conjunto de símbolos e como eles são usados para
construir mensagens no barramento. Um símbolo representa uma unidade de informação. Uma lista dos símbolos definidos pode ser vista na tabela 2.2
Símbolo
Descrição
SOF
Começo do quadro (Start Of Frame)
0
zero lógico
1
um lógico
EOD
Fim dos dados (End Of Data)
NB
Bit de Normalização (somente em VPW)
EOF
Fim do quadro (End Of Frame)
IFS
Separação de quadros (Inter-Frame Separation)
Break
Interrupção do barramento
Tabela 2.2: Símbolos do protocolo J1850 (Riley, 1998)
O barramento J1850 pode estar em dois estados: ativo e passivo. Nenhum
destes estados unicamente é usado para passar informações. Mas o estado do barramento é importante para o entendimento da definição dos vários símbolos. O
estado ativo é o dominante.
No método de transmissão do J1850, que é o CSMA/NDA, a disputa pelo barramento é não-destrutiva. Múltiplos nodos podem começar a transmissão simultaneamente. A rede define que o zero lógico é dominante. Logo, mensagens que tem
prioridade são definidas com identificadores menores. Consequentemente, quando
vários nodos estão transmitindo ao mesmo tempo, somente o nodo que transmitir
um zero final vencerá a disputa e continuará sua transmissão. Os outros nodos
verificam que perderam prioridade e interrompem seu envio (Riley, 1998).
Meio físico
A rede VPW consiste de um único fio, denominado BUS+. Quando o barramento
está no modo passivo, BUS+ está próximo de 0 V. Quando está ativo, a linha fica a
+7 V.
A rede PMW consiste em um par de fios, o BUS+ e o BUS-. No modo passivo, a
voltagem é -5 V (medição de BUS+ em relação a BUS-). Quando ativo, a voltagem
é +5 V. Com relação ao terra, o barramento passivo tem BUS+ a 0 V e BUS- a 5 V,
com as voltagens invertidas no barramento ativo (Riley, 1998).
Protocolo
Todas as comunicações no barramento J1850, assim como a grande maioria de outros protocolos, é feita atráves de quadros, ou frames. Cada frame é construído
de forma semelhante: O frame começa com o símbolo SOF, seguido do bit mais
significante do primeiro byte da mensagem. O último byte transmitido deste segmento é um CRC (cyclic redundancy check). Por fim, o símbolo EOD indica o fim
do segmento de dados.
9
Após o envio do EOD, um ou mais nodos podem responder a mensagem. Se isto
ocorrer, é chamdo de In-Frame Response (IFR). Estas respostas são opcionais. Um
símbolo EOF é transmitido após o IFR (se houve algum) para indicar que o frame
está completo.
Transmissão de um próximo frame só pode ser feita depois de um tempo determinado IFS.
2.2.2
ISO 9141-2
O padrão ISO 9141, também conhecido como padrão CARB 9141 (California Air
Resources Board). Este padrão era referenciado pela regulamentação da CARB que
foi a precursora da lei que criou o OBD-II. Mais tarde, a CARB adotou uma versão
melhorada da ISO 9141, a ISO 9141-2, com o subtítulo de CARB Requirements for
Interchange of Digital Information (Riley, 1998).
Assim como os outros padrões, este padrão descreve as camadas físicas e de
ligação de dados (relativas ao modelo de rede OSI).
Características
As principais características da rede ISO 9141-2 são:
• Meio físico: Fio duplo (sinal não balanceado)
• Taxa de transmissão: 10.4 kb/s
• Tempo de bit: 96.15 µs
A arquitetura da ISO 9141 se distancia do padrão J1850 mencionado anteriormente e, de forma geral, da maioria das estruturas de redes existentes. Uma rede
J1850 não possui um nodo central e não há o conceito de direção de sinal ou fluxo.
Em uma rede J1850, todos os nodos são semelhantes, pois qualquer um pode
transmitir e todos recebem as mensagens. De forma semelhante, símbolos e mensagens são independentes de quem está transmitindo ou recebendo.
Em uma rede compatível com ISO 9141-2, direção do fluxo de mensagem é uma
característica importante. A especificação foi escrita levando em conta a conexão
de aparelhos de medição externos a rede. A direção das mensagens e questões
quanto a temporização destas são baseadas em quem está "‘falando"’ e quem está
"‘ouvindo"’.
Meio físico
Um barramento ISO 9141 consiste de dois fios, designados linhas K e L (K-line e
L-line). A voltagem define o estado de cada linha, podendo estar em alta (1 lógico)
ou baixa voltagem (0 lógico).
Diferente do J1850, as linhas K e L não têm estados ativo ou passivo. Quando
um nodo está ligado, ambas as linhas são ligadas à alimentação da bateria. Ambas
linhas ficam ociosas no estado 1. Para um nodo transmitir um 0, ele desvia a linha
desejada para o terra e a mantém assim durante um tempo de bit.
10
A linha K é bidirecional e compartilhada por todos os nodos assim como o equipamento de teste externo. Todos os nodos ouvem esta linha e transmitem nela. A
arquitetura da linha K é semelhante a um circuito lógico OU. Isto faz com que o
um lógico seja o bit dominante, assim como no J1850.
A linha L é unidirecional, e somente o equipamento externo pode transmitir
nela. Módulos que suportam diagnóstico externo têm que ouvir esta linha (Riley,
1998).
Protocolo
Uma rede ISO 9141 é baseada no UART (Universal Asynchronous Receiver/Transmitter), que é encontrado em outros padrões de comunicação como o RS-232.
São usados bits de início e parada. A sinalização é de não retorno a zero. Todos
os símbolos são transmitidos no tempo de bit fixado. O bit de início é o 0 lógico
durante um tempo de bit, enquanto o bit de parada é o 1 lógico.
Todas as mensagens são transmitidas em um ou mais bytes. Cada byte é enviado como um pacote de bits, sendo cada byte precedido pelo bit de início. Oito bits
de dados são usados, sendo enviados na ordem do menos ao mais significativo. O
bit de parada é anexado ao fim.
Diferentemente do J1850, não existem símbolos especiais de início ou fim do
quadro. O significado de um byte na mensagem em comparação com outro ou se
uma mensagem termina e outra começa é estritamente uma função de tempo.
A especificação define janelas para todos parâmetros temporais, um para cada
situação. Alguns exemplos de janelas são o tempo entre bytes provindos do equipamento externo ou o tempo do fim de uma mensagem do veículo até o início da
próxima mensagem do equipamento externo.
Os vários tempos são denotados como tempos W e P. Pelo menos um deles é
dinamico e dependente de quando o equipamento está enviando uma mensagem.
O tempo W se aplica durante a fase de inicialização e o tempo P se aplica durante
as outras fases.
Quando um computador conecta-se a uma interface J1850 e envia uma mensagem de requisição OBD-II, como por exemplo a pressão do óleo (assumindo que o
sistema está operando corretamente), o veículo irá responder com uma mensagem
com os dados requisitados. Se isto for feito em uma rede ISO 9141-2, não conseguirá obter uma resposta.
Antes de um equipamento externo poder se comunicar com o computador a
bordo, de acordo com a ISO 9141-2, a comunicação deve ser iniciada. A sequência de iniciação permite que as duas partes, o equipamento externo e o computador
de bordo, se reconheçam um ao outro e o meio com que eles se comunicarão.
Em essência, assim acontece o básico da iniciação:
1. O equipamento externo envia o código 51 a 5 bauds em ambas as linhas K e
L. Depois, a linha L é desabilitada e fica ociosa.
2. Os componentes do veículo acordam se não estiverem ativos, mas somente o
computador responsável pelo diagnóstico responde com o código 85 à taxa de
10.4 kb/s. Este é o byte de sincronização.
11
3. Todas as comunicações agora são feitas a 10.4 kb/s.
4. O computador de bordo envia duas palavras chaves, #1 e #2, ambas valores
de um byte.
5. O equipamento externo responde enviando uma inversão bit a bit da palavra
#2.
6. O veículo responde enviando a inversa do comando de incialização enviada
pelo equipamento no primeiro passo.
7. A partir de então, a comunicação está estabelecida e operacional.
Uma vez que a ligação esteja feita, ela deve ser mantida. Se não houver tráfego no barramento por 5 segundos, cada computador assume que as comunicações
estão encerradas. A inicialização deve ser repetida para re-estabelecimento das comunicações. O equipamento pode transmitir periodicamente uma mensagem para
manter a ligação ativa (Riley, 1998).
2.2.3
ISO 14230-4
O ISO 14230-4, também conhecido como KWP2000 (Keyword Protocol 2000), é uma
extensão do ISO 9141-2, compartilhando o mesmo meio físico e outras características, sendo a principal diferença a capacidade de enviar mensagens muito maiores,
260 bytes no máximo ao contrário de 11 bytes do protocolo 9141-2 (Dzhelekarski
and Alexiev, 2005b). Assim como o 9141-2, é usado principalmente na Europa e
Ásia.
2.2.4
Low-speed CAN (Controller Area Network)
O CAN está se tornando o protocolo padrão para comunicação entre os componentes
eletrônicos nos veículos, já existindo norma norte-americana tornando obrigatória
sua aplicação.
História e aplicações
O Controller Area Network é um barramento de comunicações serial voltado para
aplicações de controle em tempo real; operando a uma taxa de até 1 Mbps, com
excelente detecção de erro e recursos de confinamento.
O CAN foi originalmente desenvolvido por uma empresa alemã automobilística,
a Robert Bosch, com o intuito de prover um barramento de comunicação a um custo
efetivo para componentes eletrônicos nos veículos e como uma alternativa aos emaranhados de fios e conectores que eram caros e não confiáveis. A indústria automobilística continua usando o CAN em um crescente número de aplicações, mas pela
sua robustez e confiabilidade, CAN está também sendo usado em muitas outras
aplicações. Este é um padrão aberto, documentado na ISO 11898 (para aplicações
em alta velocidade) e na ISO 11519 (para conexões em baixa velocidade) (Kvaser
AB, 2009; Pazul, 1999; Schofield, 1996).
12
Diversos controladores CAN e dispositivos de interface estão disponíveis à venda
por muitos dos principais manufaturadores de semicondutores. Existe também
uma infinidade de pacotes de desenvolvimento de sistemas baseados em CAN, placas de interface e kits de desenvolvimento de sistemas (SDKs) que provém as ferramentas necessárias para construir, monitorar, testar e analisar sistemas baseados
em CAN. Consequentemente, a maioria dos automóveis hoje na Europa, e cada vez
mais no resto do mundo, já usam a tecnologia CAN em seus sistemas (Schofield,
1996).
Controladores e interfaces CAN são fisicamente pequenos, operando em altas
velocidades e em ambientes hostis. Estas propriedades levaram o CAN a ser usado
em muitas outras aplicações além da automobilística. Alguns exemplos:
• Sistemas de controle e navegação naval
• Sistemas de controle de elevadores
• Máquinas agrícolas
• Equipamentos médicos
Meio físico
O CAN usa codificação sem retorno a zero (NRZ) e com bit-stuffing (técnica para
diferenciar sequência de bits de delimitadores) para transmissão de dados em um
barramento diferencial em dois fios. O uso da codificação NRZ garante mensagens
compactas e com alta resistência a interferências externas.
O barramento em fio duplo é normalmente feito em par trançado. Par simples
também pode ser usado mas é mais suscetível a interferência.
Uma das características do CAN que reforçam sua confiabilidade é uma recomendação da ISO 11898 que recomenda que os chips de interface do barramento
sejam feitos de tal forma que a comunicação possa continuar (mas com uma reduzida relação sinal-ruído) mesmo que:
• Qualquer um dos fios do barramento se rompa
• Qualquer um dos fios esteja em curto na fonte
• Qualquer um dos fios esteja em curto no terra
Protocolo
Um dos princípios do CAN é que mensagens transmitidas de qualquer nodo no
barramento não contém nenhum endereço, nem de remetente e nem de destino.
Ao invés disso, o conteúdo da mensagem é identificado por um identificador que
é único através da rede. Todos os nodos na rede recebem a mensagem e cada um
verifica o identificador único para determinar se o conteúdo da mensagem é de seu
interesse. Se a mensagem for de interesse, ela é processada; caso contrário ela é
ignorada.
13
Esta orientação a conteúdo das mensagens do CAN tem como consequência um
alto grau de flexibilidade na configuração do sistema. Novos nodos que são puramente receptores podem ser adicionados a rede sem necessidade de maiores mudanças ao software e hardware existentes.
Para delegação do envio de mensagem, o CAN usa o método conhecido como
CSMA/CD, mas com a melhoria de que a detecção de colisão não interrompe o envio
da mensagem prioritária.
A prioridade da mensagem é determinada pelo valor numérico do seu identificador. Este valor é definido durante a fase inicial do desenvolvimento do sistema.
O identificador com o valor numérico mais baixo tem a maior prioridade. Isto acontece pelo comportamento do barramento, que funciona como uma porta lógica AND,
ou seja, enquanto algum nodo transmitir o valor lógico zero, o barramento terá
este valor. No momento que o canal está disponível, os nodos que querem transmitir começam a transmissão do seu identificador, monitorando o barramento ao
mesmo tempo. No momento em que ele envia o valor 1 mas o barramento continua 0, significa que outro nodo está transmitindo uma mensagem prioritária (valor
do identificador é menor), logo este nodo interrompe sua transmissão, enquanto o
nodo prioritário não precisa interromper sua transmissão.
Esta estratégia oferece maior aproveitamento do barramento, baseado na necessidade dos nodos, não havendo interrupções de transmissão por colisão, o que
não pode ser conseguido através de protocolos de tempo fixo como o Token Ring e
nem com barramentos de alocação destrutiva como o Ethernet. Mas cuidado deve
ser tomado no desenvolvimento da rede, pois nodos prioritários em excesso podem
tomar a rede e não dar chance aos nodos menos prioritários.
Com este comportamento, o CAN permite, por exemplo, que parâmetros que
mudam mais frequentemente como as rotações por minuto (RPM) do motor tenham
prioridade sobre valores que mudam menos frequentemente, como a temperatura
do motor.
Em um sistema CAN, assim como em outros procolos de rede, as mensagens são
transmitidas em quadros de dados (Message Frames), que contém os dados sendo
transmitidos por um nodo, além de dados de controle e checagem de erro. A última
especificação do CAN definem duas versões, a versão 2.0A denominada o CAN padrão (Standard CAN) e a versão 2.0B, o CAN estendido (Extended CAN). Um esquema do formato do quadro usado pelo CAN 2.0A pode ser visto na figura 2.2.
O quadro de dados do CAN padrão consiste de sete campos de bits:
• Start of Frame (SOF): Indica o início do quadro. Único bit de valor zero.
• Arbitration field: O identificador único, com 11 bits, mais um bit conhecido
como Remote Transmission Request (RTR) bit. Este bit serve para diferenciar
entre um quadro de envio de dados e um quadro de requisição.
• Control Field: Contém 6 bits, sendo os 2 primeiros bits reservados para uso
futuro e os outros 4 bits são o Data Length Code (DLC) que indica o tamanho
em bytes do próximo campo, o Data field.
• Data field: Os dados sendo enviados, podendo conter de 0 a 8 bytes.
14
Figura 2.2: Quadro de dados do protocolo CAN 2.0A
• CRC field: Contém um código de verificação de redundância cíclica em 15 bits
para verificação de erros no Data field e mais um bit delimitador.
• ACKnowledge field: Campo usado para confirmação de recebimento pelos outros nodos. O primeiro bit é enviado como recessivo no barramento mas é
logo sobrescrito por bit dominante pelos outros nodos para confirmar o recebimento. O outro bit é um delimitador recessivo.
• End of frame field: Último campo, consistindo de 7 bits recessivos, indica o
fim do quadro.
O quadro de dados do CAN 2.0B pode ser visto na figura 2.3. O CAN 2.0B foi criado para prover compatibilidade com outras comunicações seriais. Para continuar
compatível com o padrão 2.0A, o quadro de dados tomou uma forma estendida do
quadro 2.0A. As diferenças estão no Arbitration field: Existem agora 2 identificadores. Um de 11 bits como no 2.0A e outro com 18 bits, formando o total de 29 bits
para identificação. Entre estes campos, 2 bits são inseridos. O Substitute Remote
Request (SRR) é um bit recessivo de forma que mensagens 2.0A que contenham
o mesmo identificador de 11 bits tenham prioridade sobre as mensagens 2.0B. O
Identifier Extension (IDE) é o bit que identifica uma mensagem 2.0B.
Figura 2.3: Quadro de dados do protocolo CAN 2.0B
A maioria dos controladores 2.0A transmitem e recebem somente mensagens
de seu formato, mas alguns, conhecidos como 2.0B passivos, recebem mas igno15
ram mensagens 2.0B, possibilitando o funcionamento em conjunto com dispositivos
2.0B.
Sincronização e tempo de bit
Não existe um sinal de clock para sincronização dos nodos em uma rede CAN. Ainda
assim, este é um protocolo que trabalha de forma síncrona.
O tempo de transmissão de cada bit é controlado internamente em cada nodo.
Cada nodo em uma rede CAN deve possuir um oscilador e uma taxa chamada Baud
Rate Prescaler (BRP) que é programada no momento da instalação do nodo. A taxa
do oscilador e o BRP multiplicados resultam numa unidade chamada time quanta.
O tempo de bit no CAN é dividido em quatro segmentos de tempo, cada qual
com seus valores em time quanta:
1. Sync-seg: Segmento para sincronia dos nodos no barramento. (1 time quanta)
2. Prop-Seg: Tempo para compensação de atrasos físicos. (1 a 8 time quantas)
3. Phase-seg1: É um segmento de buffer, que pode ser aumentado para ressincronização para compensar diferenças positivas na fase dos osciladores. (1 a
8 time quantas)
4. Phase-seg2: É um segmento de buffer, que pode ser diminuído para ressincronização para compensar diferenças negativas na fase dos osciladores. (Igual
a Phase-seg1)
A sincronia dos sinais ocorre durante a transmissão de cada bit, quando é verificado o tempo onde houve a mudança de sinal em Sync-seg. Dependendo do atraso
que ocorre, Phase-seg1 e Phase-seg2 são alterados pelos nodos para a sincronia dos
sinais.
2.3
Classe C
Para aplicações que necessitam de comunicação em tempo-real e alta velocidade.
Utilizadas principalmente nos primeiros dois domínios. Redes classe C como o CAN
de alta velocidade (high-speed CAN) operam na faixa de 125kb/s a 1Mb/s.
2.3.1
High-speed CAN
O protocolo CAN suporta taxas de transmissão entre 40Kbps (Classe B) e 1Mbps
(Classe C) dependendo do meio físico e da distância entre os nodos. O protocolo
funciona de forma semelhante, mudando somente a taxa de transmissão. Desta
forma o protocolo pode ser usado transparentemente em ambas as classes (Pazul,
1999; Schofield, 1996).
16
2.3.2
TTP/C
TTP/C é um protocolo determinístico desenvolvido pela Universidade de Vienna,
derivado de dois projetos desta univerdade (X-by-write e TTA). Desde a conclusão
de tais projetos, a especificação do protocolo foi transferida para a empresa TTTech (controlada por um consórcio de outras empresas com a Volkswagen, Audi e
Honeywell) (Kopetz and Grunstidl, 1993).
TTP/C é baseado em intervalos de tempo (TDMA), ao contrário do CAN, que
é baseado em eventos (CSMA). Cada nodo é sincronizado por um clock comum.
Todas transmissões são feitas em pontos específicos de tempo, definidos na fase
de especificação do sistema. Como o TTP/C é um protocolo TDMA, a latência é
determinística. Nenhum nodo pode monopolizar o meio de comunicação além do
seu intervalo de tempo (TTA Group, 2004).
2.4
Classe D
Estas redes operam em velocidades acima de 1Mbps e são utilizadas para aplicações multimídia. Exemplos são MOST e FlexRay.
2.4.1
MOST
MOST é uma rede orientada a funcionalidades, multimídia e de alta velocidade. O
protocolo define mecanismos para envio tanto de dados em pacotes como em fluxos
(streaming), além de prover um completo framework de aplicação para controlar
a interação entre os componentes da rede de forma estruturada. MOST suporta
também diferentes taxas de velocidade e meios físicos (MOST Cooperation, 2008).
Uma rede MOST consiste de até 64 nodos. É uma rede síncrona (TDMA), onde
há um nodo mestre responsável pela sincronização dos demais. Desta forma, a
banda alocada para conexões de streaming está sempre disponível e reservada para
que não haja interrupções, colisões ou atrasos no envio dos dados, possibilitando
alta qualidade de serviço e eficiente transmissão de áudio e vídeo.
Tráfego da Internet ou informação de sistemas de navegação são tipicamente
enviados em pacotes assíncronos, e distribuídos para diferentes nodos. Para suportar tais sinais, MOST define eficientes mecanismos para o envio e tratamento de
tais pacotes além dos dados de controle e streaming. Porém, o envio destes dados se
dá de forma separada dos dados de streaming, de forma que não haja interferência
entre eles.
Em suma, MOST é uma rede designada para transportar os diversos tipos de
dados e sinais que tem origem em sistemas multimídia e de entretenimento.
2.4.2
FlexRay
Flexray é um protocolo de comunicação em tempo real composto de partes estáticas
e dinâmicas. Baseado em uma forma estendida de TDMA, o ciclo de comunicação
deve ser definido juntamente com sua duração quando a rede é configurada. Este
17
elemento fundamental do esquema de acesso à mídia consiste de um segmento estático mandatório, um segmento dinâmico opcional e dois segmentos de protocolo
chamados janela de símbolos (symbol window, responsável pelo envio de mensagens de sistema especiais como emphwake-up e emphstartup.), também opcional,
seguidos de um tempo de inatividade mandatório que marca o fim do envio de dados (FlexRay Consortium, 2005). Na figura 2.4 podemos ver um esquema do ciclo
de comunicação.
Figura 2.4: Ciclo de comunicação do protocolo FlexRay
No segmento estático, o tempo determinístico de comunicação é responsável por
requisitos importantes como a latência, utilizando TDMA com intervalos de tempo
de mesmo tamanho, com cada ECU possuindo seu intervalo de tempo exclusivo,
certificando-se da transmissão de seus dados sem interrupções.
No segmento dinâmico é onde comunicações baseadas em eventos são feitas. A
estratégia usada é uma extensão do TDMA, denominada FTDMA (FlexRay timedivision multiple access), criando um padrão de acesso por demanda ainda baseado em tempo para comunicações dinâmicas. A estratégia é baseada em miniintervalos de tempo, que basicamente dão a chance de algum ECU requisitar um
envio. Quando há uma requisição, um mini-intervalo é expandido para um intervalo padrão para uso do ECU. Caso contrário, mini-intervalos continuam sendo
enviados.
18
Capítulo 3
Aquisição de dados
O básico de um sistema de telemetria é a aquisição dos dados. Felizmente os carros
hoje possuem diversas ECUs que fazem medições dos parâmetros funcionais do veículo. Estas unidades eletrônicas formam o que se chama de sistema de diagnóstico
a bordo (On-board diagnostics, mais conhecido pela sigla OBD).
3.1
OBD
A sigla OBD vem sido usada há muito tempo, quando começaram a surgir equipamentos de diagnósticos em veículos. Os primeiros sistemas consistiam somente de
uma luz indicadora de problema no motor ou painel (MIL - Malfunction indicator
light) quando um problema era detectado.
Implementações mais modernas de OBDs usam uma porta padrão de comunicação digital para prover informações em tempo real sobre o funcionamento do
veículo. Há também códigos padronizados de diagnóstico de problemas (DTC - diagnostic trouble codes) que permitem que problemas sejam detectados e resolvidos
rapidamente.
Um outro motivador para a implantação de um sistema OBD padronizado, como
será observado a seguir, é a medição de emissão de poluentes do carro. Um sistema
de medição padrão torna muito mais fácil e confiável a medição da emissão dos
veículos.
3.1.1
História
• 1975: Computadores embarcados começam a aparecer nos veículos civis com
o Datsun 280z, motivado principalmente pela necessidade de ajuste em tempo
real de sistemas de injeção eletrônica. Com isso, começam a aparecer as primeiras implementações de OBD, mas sem um padrão definido do quê e como
é feita a monitoração.
• 1980: A General Motors implementa um protocolo proprietário chamado ALDL,
que se comunica a 160 baud e monitora poucos sistemas do veículo.
• 1986: Uma versão melhorada do ALDL é criada, que se comunica a 8192
bauds. O protocolo é definido no padrão GM XDE-5024B.
19
• 1987: A California Air Resources Board - CARB, agência do estado norteamericano que define políticas em prol da preservação da qualidade do ar,
ergue uma norma de que todos os veículos vendidos no estado a partir de 1988
tenham um sistema básico OBD implantado. Não foi definido um padrão para
conexão nem protocolo de dados.
• 1988: A sociedade de engenheiros automotivos SAE (Society of Automotive
Engineers) recomenda um padrão para conectores e sinais de diagnóstico (Padrão hoje conhecido como OBD-I).
• 1994: A CARB lança a especificação OBD-II e ergue a norma de que deve ser
adotado em todos os carros vendidos na Califórnia a partir de 1996. Os conectores e protocolos sugeridos pela SAE são incorporados nesta especificação.
• 1996: O OBD-II se torna mandatório em todos os carros vendidos nos Estados
Unidos.
• 2001: A União Europeia especifica o EOBD (padrão baseado no OBD-II) para
todos os veículos vendidos na União Europeia.
• 2004: O Conselho Nacional do Meio Ambiente Ű CONAMA, inspirado nas
normas internacionais estabelecidas, lança a resolução 354 de 13 de dezembro
de 2004, que define o OBDBr-1 e OBDBr-2, sistema OBD a ser implantado
nos veículos brasileiros. A resolução se apoia nas normas internacionais já
publicadas para o conector e define quais as medições que deverão ser feitas
em cada versão.
• 2007: 40% dos carros brasileiros devem implantar o OBDBr-1.
• 2008: A partir deste ano, todos os carros vendidos nos Estados Unidos devem
implentar o padrão de sinalização ISO 15765-4 (baseado no protocolo CAN Controller Area Network).
• 2009: 100% dos carros brasileiros devem implantar o OBDBr-1.
3.1.2
Padrões OBDBr-1 e OBDBr-2
A CONAMA, com a resolução 354 de 13 de dezembro de 2004, definiu o padrão
de sistemas de diagnose para os veículos brasileiros. O padrão foi baseado no já
existente e implantado OBD-II. A principal tarefa da resolução foi definir os parâmetros a serem medidos e prazo para implantação pelas montadoras (CONAMA,
2006).
Parâmetros do OBDBr-1, implantando em 40% dos automóveis em 2007, 60%
em 2008 e 100% em 2009:
• Sensor Pressão Absoluta ou Fluxo de Ar
• Sensor Posição da Borboleta
• Sensor de Temperatura de Arrefecimento
• Sensor Temperatura de Ar
20
• Sensor Oxigênio (somente o sensor pré-catalisador)
• Sensor de Velocidade do Veículo
• Sensor de Posição do Eixo Comando de Válvulas
• Sensor de Posição do Virabrequim
• Sistemas de Re-circulação dos Gases de Escape (EGR)
• Sensor para Detecção de Detonação
• Válvulas Injetoras
• Sistema de Ignição
• Módulo Controle Eletrônico do motor
• Lâmpada Indicadora de Mau Funcionamento (LIM)
• Outros componentes que o fabricante julgue relevantes para a correta avaliação do funcionamento do veículo e controle de emissões de poluentes.
Complementarmente às funções e características do Sistema OBDBr-1, o sistema OBDBr-2 deve detectar e registrar a existência de falhas de combustão, deterioração do(s) sensor(es) de oxigênio primário(s) e eficiência de conversão do catalisador que acarretem aumento de emissões, também apresentar características
mínimas para a detecção de falhas nos seguintes componentes:
• Sensores de Oxigênio (pré e pós-catalisador)
• Válvula de Controle da Purga do Cânister
O sistema OBDBr-2 começará a ser implantando em 2010.
3.1.3
Padrão OBD-II
O padrão difundido para quase a totalidade dos veículos para monitoramento e
diagnóstico eletrônico é o OBD-II. Este padrão define um conector de diagnóstico
padrão e sua pinagem, os protocolos de sinalização disponíveis e o formato das mensagens. Há também a definição de alguns parâmetros que devem ser monitorados
e como devem ser codificados, além dos códigos de detecção de problemas, os DTCs.
Graças a este padrão, é possível a construção de dispositivos que sejam capazes de
diagnosticar qualquer veículo que o implemente.
Conector OBD-II
A padrão OBD-II especifica uma interface de hardware - o conector fêmea de 16
pinos (2x8) J1962 (Dzhelekarski and Alexiev, 2005a). Este conector deve aparecer
no compartimento de passageiros, perto do console central do veículo, do lado do
motorista. A especificação do J1962 feita pela SAE define as pinagens do conector
como:
21
Figura 3.1: Esquema do conector OBD-II
1. 2. Linha de barramento positiva do SAE-J1850
3. Ford DCL positivo
4. Terra da bateria
5. Terra de sinal
6. CAN alta voltagem (ISO 15765-4, SAE J2284)
7. Linha K dos ISO 9141-2, 14230-4
8. 9. 10. Negativo do SAE J1850
11. Ford DCL negativo
12. 13. 14. CAN baixa voltagem
15. Linha L dos ISO 9141-2, 14230-4
16. Alimentação da bateria
A implementação dos pinos não especificados está a critério do fabricante.
Protocolos
Cinco protocolos são definidos no padrão OBD-II, como pode ser notado pela pinagem. Um veículo normalmente implementa somente um deles. Estes protocolos
eram e ainda são os mais usados na época da definição do padrão. Logo, o dispositivo que fizer a leitura dos dados deve estar preparado para lidar com todos os
5 protocolos se deseja ser totalmente compatível com OBD-II (Dzhelekarski and
Alexiev, 2005b).
• SAE J1850 PWM
22
• SAE J1850 VPW
• ISO 9141-2
• ISO 14230 KWP2000 (Keyword Protocol 2000)
• ISO 15765 CAN (Controller Area Network)
Estes protocolos são abordados com mais detalhes na seção 2.2.
Interface OBD x computador
Já existem diversas interfaces implementadas para conexão do OBD-II com computadores. Normalmente esta conexão é feita pela porta serial RS-232, ou, mais
recentemente, a USB.
A empresa ELM electronics criou o que é hoje conhecido como o estado da arte na
interface de computadores com o OBD: O chip ELM 327 (ELM Electronics, 2009).
Com este chip conectado a uma interface serial, é possível acessar dados OBD de
forma padronizada, sem diferenças no protocolo implementado pelo carro. O chip é
responsável por interpretar o protocolo utilizado pelo carro e transformar os dados.
A comunicação com o ELM 327 é feita através de comandos AT, semelhante a
um modem, o que facilita a implementação de sistemas para recuperação dos dados
necessários.
Hoje já existem versões semelhantes inspiradas no ELM 327, implementando
o mesmo padrão, de design aberto e fácil construção. Por isto este será o modelo
de conector usado no projeto. Um dos modelos é mostrado abaixo, criado por Alex
Sidorenko, que disponibilizou o circuito, as peças e o firmware para o microcontrolador PIC18F2455 em seu website (Sidorenko, 2009).
Figura 3.2: Interface OBD x USB de Alex Sidorenko
Dados mensurados
O padrão OBD definido pela SAE estabelece os dados que podem ser disponibilizados pela porta OBD aos equipamentos de diagnóstico. A tabela 3.1 mostra uma
lista dos dados, seus códigos identificadores (PID - Parameter ID) que são utilizados pelas ferramentas de diagnóstico para fazer a consulta, número de bytes e a
unidade de medida que representam.
23
Figura 3.3: Esquema elétrico da interface OBD x USB de Alex Sidorenko
24
Tabela 3.1: Dados OBD-II
PID
0
1
2
3
4
5
6
7
8
9
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D
1E
1F
20
21
22
23
24
25
26
27
28
Bytes
4
4
8
2
1
1
1
1
1
1
1
1
2
1
1
1
2
1
1
1
2
2
2
2
2
2
2
2
1
1
1
2
4
2
2
2
4
4
4
4
4
Descrição
Unidade
PIDs supported [01 - 20]
Monitor status since DTCs cleared.
Freeze DTC
Fuel system status
Calculated engine load value
%
◦
Engine coolant temperature
C
Short term fuel % trim Bank 1
%
Long term fuel % trim Bank 1
%
Short term fuel % trim Bank 2
%
Long term fuel % trim Bank 2
%
Fuel pressure
kPa (gauge)
Intake manifold absolute pressure
kPa (absolute)
Engine RPM
rpm
Vehicle speed
km/h
◦
Timing advance relative to #1 cylinder
◦
Intake air temperature
C
MAF air flow rate
g/s
Throttle position
%
Commanded secondary air status
Oxygen sensors present
Bank 1 Sensor 1: Oxygen sensor
Volts %
Bank 1 Sensor 2: Oxygen sensor
Volts %
Bank 1 Sensor 3: Oxygen sensor
Volts %
Bank 1 Sensor 4: Oxygen sensor
Volts %
Bank 2 Sensor 1: Oxygen sensor
Volts %
Bank 2 Sensor 2: Oxygen sensor
Volts %
Bank 2 Sensor 3: Oxygen sensor
Volts %
Bank 2 Sensor 4: Oxygen sensor
Volts %
OBD standards this vehicle conforms to
Oxygen sensors present
Auxiliary input status
Run time since engine start
seconds
PIDs supported 21-40
Distance traveled with MIL on
km
Fuel Rail Pressure (relative to manifold vacuum) kPa
Fuel Rail Pressure (diesel)
kPa (gauge)
O2S1_WR_lambda(1): Equivalence Ratio Voltage N/A V
O2S2_WR_lambda(1): Equivalence Ratio Voltage N/A V
O2S3_WR_lambda(1): Equivalence Ratio Voltage N/A V
O2S4_WR_lambda(1): Equivalence Ratio Voltage N/A V
O2S5_WR_lambda(1): Equivalence Ratio Voltage N/A V
Continua na próxima página. . .
25
PID
29
2A
2B
2C
2D
2E
2F
30
31
32
33
34
35
36
37
38
39
3A
3B
3C
3D
3E
3F
40
41
42
43
44
45
46
47
48
49
4A
4B
4C
4D
4E
51
52
100
101
Tabela 3.1 – continuação
Bytes
Descrição
Unidade
4
O2S6_WR_lambda(1): Equivalence Ratio Voltage N/A V
4
O2S7_WR_lambda(1): Equivalence Ratio Voltage N/A V
4
O2S8_WR_lambda(1): Equivalence Ratio Voltage N/A V
1
Commanded EGR
%
1
EGR Error
%
1
Commanded evaporative purge
%
1
Fuel Level Input
%
1
# of warm-ups since codes cleared
N/A
2
Distance traveled since codes cleared
km
2
Evap. System Vapor Pressure
Pa
1
Barometric pressure
kPa (Absolute)
4
O2S1_WR_lambda(1): Equivalence Ratio Current N/A mA
4
O2S2_WR_lambda(1): Equivalence Ratio Current N/A mA
4
O2S3_WR_lambda(1): Equivalence Ratio Current N/A mA
4
O2S4_WR_lambda(1): Equivalence Ratio Current N/A mA
4
O2S5_WR_lambda(1): Equivalence Ratio Current N/A mA
4
O2S6_WR_lambda(1): Equivalence Ratio Current N/A mA
4
O2S7_WR_lambda(1): Equivalence Ratio Current N/A mA
4
O2S8_WR_lambda(1): Equivalence Ratio Current N/A mA
◦
2
Catalyst Temperature Bank 1 Sensor 1
C
◦
C
2
Catalyst Temperature Bank 2 Sensor 1
◦
2
Catalyst Temperature Bank 1 Sensor 2
C
◦
2
Catalyst Temperature Bank 2 Sensor 2
C
4
PIDs supported 41-60
4
Monitor status this drive cycle
2
Control module voltage
V
2
Absolute load value
%
2
Command equivalence ratio
N/A
1
Relative throttle position
%
◦
1
Ambient air temperature
C
1
Absolute throttle position B
%
1
Absolute throttle position C
%
1
Accelerator pedal position D
%
1
Accelerator pedal position E
%
1
Accelerator pedal position F
%
1
Commanded throttle actuator
%
2
Time run with MIL on
minutes
2
Time since trouble codes cleared
minutes
1
Fuel Type
1
Ethanol fuel%
%
OBD Monitor IDs supported (01−20)
O2 Sensor Monitor Bank 1 Sensor 1
Volts
Continua na próxima página. . .
26
Tabela 3.1 – continuação
PID Bytes
Descrição
102
O2 Sensor Monitor Bank 1 Sensor 2
103
O2 Sensor Monitor Bank 1 Sensor 3
104
O2 Sensor Monitor Bank 1 Sensor 4
105
O2 Sensor Monitor Bank 2 Sensor 1
106
O2 Sensor Monitor Bank 2 Sensor 2
107
O2 Sensor Monitor Bank 2 Sensor 3
108
O2 Sensor Monitor Bank 2 Sensor 4
109
O2 Sensor Monitor Bank 3 Sensor 1
010A
O2 Sensor Monitor Bank 3 Sensor 2
010B
O2 Sensor Monitor Bank 3 Sensor 3
010C
O2 Sensor Monitor Bank 3 Sensor 4
010D
O2 Sensor Monitor Bank 4 Sensor 1
010E
O2 Sensor Monitor Bank 4 Sensor 2
010F
O2 Sensor Monitor Bank 4 Sensor 3
110
O2 Sensor Monitor Bank 4 Sensor 4
201
O2 Sensor Monitor Bank 1 Sensor 1
202
O2 Sensor Monitor Bank 1 Sensor 2
203
O2 Sensor Monitor Bank 1 Sensor 3
204
O2 Sensor Monitor Bank 1 Sensor 4
205
O2 Sensor Monitor Bank 2 Sensor 1
206
O2 Sensor Monitor Bank 2 Sensor 2
207
O2 Sensor Monitor Bank 2 Sensor 3
208
O2 Sensor Monitor Bank 2 Sensor 4
209
O2 Sensor Monitor Bank 3 Sensor 1
020A
O2 Sensor Monitor Bank 3 Sensor 2
020B
O2 Sensor Monitor Bank 3 Sensor 3
020C
O2 Sensor Monitor Bank 3 Sensor 4
020D
O2 Sensor Monitor Bank 4 Sensor 1
020E
O2 Sensor Monitor Bank 4 Sensor 2
020F
O2 Sensor Monitor Bank 4 Sensor 3
210
O2 Sensor Monitor Bank 4 Sensor 4
0
4
mode 9 supported PIDs 01 to 20
2
5x5
Vehicle identification number (VIN)
4
varies calibration ID
27
Unidade
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Volts
Capítulo 4
Telefonia móvel
Com o avanço da tecnologia de telefonia móvel, cada vez mais os aparelhos portáteis ficam poderosos, portando sistemas computacionais complexos e capacidades
de conectividade cada vez mais rápidas e simples, assim como cresce os recursos
eletrônicos nos automóveis. Mas ainda existe uma lacuna a ser preenchida que é
a integração desses dois mundos, criando recursos e facilidades para o usuário do
veículo e de tecnologias móveis.
Estudos para a criação de aparelhos de transmissão e recepção por células, os
aparelhos celulares, começaram a ser feitos em meados de 1950. Antes, a telefonia
dependia de conexão direta cabeada dos aparelhos até uma central de comunicação.
Coincidentemente, a ideia inicial do uso desta forma de comunicação era para o uso
em automóveis.
A primeira rede de telefonia celular era conhecida como AMPS (Advanced Mobile Phone Server) e foi lançada em 1983. Logo em 1987, estas redes começaram
a apresentar grande demanda e consequentemente, congestionamento. Para aumentar a eficiência do serviço, novas tecnologias foram implantadas, com o TDMA
(Time Division Multiple Access), CDMA (Code Division Multiple Access) e GSM
(Global System for Mobile Communications).
O fenômeno da tecnologia de telefonia móvel impactou o mundo como poucas
tecnologias modernas conseguiram. Hoje, cerca de 81% da população brasileira
possui celular (Anatel, 2009).
Por já estar profundamente inserida no cotidiano das pessoas, a telefonia celular tem sido uma plataforma constantemente visada para integração de serviços e
recursos. Os bancos, por exemplo, disponibilizam mensagens aos clientes com confirmações de movimentações, sistemas para controle da conta por telefone celular,
entre outros recursos. Nada mais óbvio para um sistema embarcado automotivo
também fazer uso desta tecnologia, utilizando-a tanto como meio de comunicação
como meio de interação com seu proprietário.
4.1
GSM
Muitos protocolos e padrões surgiram durante a criação da telefonia celular, mas
nenhum conseguiu a ampla aceitação que hoje tem o GSM, sendo usado em cerca
de 80% das operadoras de telefonia celular do mundo (GSM Association, 2009).
28
O GSM foi criado na Europa em 1990, onde antes cada país tinha o seu próprio
sistema analógico de telefonia celular, impedindo a compatibilidade entre as redes
e seus aparelhos. A ideia do novo padrão era prover interconexão não só entre as
redes de diferentes países, mas prover integração com outros sistemas. Por isso
o padrão analógico foi abandonado em favor do padrão digital. Esta característica
possibilitou a construção de recursos digitais com o SMS e o GPRS (Scourias, 1997).
4.1.1
SMS
Com o SMS (Short Message System), usuários de redes GSM podem trocar mensagens alfanuméricas de até 160 caracteres. As mensagens podem ser trocadas
entre redes, em qualquer lugar do mundo, e são recebidas em segundos. A idéia
original era ser um simples sistema de notificação a usuários de uso da operadora,
como avisos de recados na caixa de mensagens, mas acabou tornando-se extremamente popular e usado pela maioria dos usuário de telefonia móvel (Peersman and
Cvetkovic, 2000).
A popularidade do SMS se deve ao fato de que pode ser transmitida a qualquer
momento, mesmo quando o destinatário está indisponível para a recepção. A operadora espera até o aparelho de destino estiver ligado e em área de cobertura para
fazer o envio. Assim como um e-mail, a mensagem quando é enviada fica guardada
no destino e pode ser acessada a qualquer momento.
Vários sistemas já fazem uso de SMS em seus serviços. Operadoras de cartão
de crédito enviam confirmações de compra por SMS, lojas online notificam usuários
quando suas compras são enviadas ou quando há algum problema na cobrança,
entre muitos outros usos.
O SMS é implementado em uma rede GSM através do uso de MSC (Message
Service Center). Seu funcionamento é semelhante a uma caixa de correio eletrônico,
onde as mensagens são organizadas por destinatário e são remetidas para a rede de
destino. Um exemplo de rede GSM com servidores MSC pode ser vista na figura 4.1.
4.1.2
GPRS
O GPRS (General packet radio service) é um protocolo que foi incorporado ao GSM
para prover serviço de transmissão de pacotes. O GPRS possibilita que aparelhos
da rede GSM interajam com outras redes digitais, mais notavelmente a Internet.
A taxa de transmissão é entre 56 e 114 kbps (Scourias, 1997).
Este serviço aumentou exponencialmente a quantidade de recursos disponíveis
nos aparelhos celulares. Telefones agora acessam páginas de Internet, atualizamse e carregam conteúdos como músicas, jogos, vídeos e imagens.
A arquitetura GPRS funciona sobre a GSM, adicionando novos nós na rede chamados GSN (GPRS Support Node) que fazem o roteamento dos pacotes de dados
entre as redes interna e externa, de forma muito semelhante à arquitetura SMS.
Podemos ver esta arquitetura ilustrada, juntamente com a arquitetura SMS, na
figura 4.1. Os principais elementos mostrados são:
• MS (Mobile Station): O dispositivo móvel sendo conectado.
29
Figura 4.1: Uma rede GSM com nós SMS e GPRS (Junior, 2005)
• BTS (Base Transceiver Station): Transceptores e antenas, responsáveis pela
transmissão dos sinais de rádio com o MS.
• BSC (Base Station Controller): Estação de controle das BTS.
• SGSN (Serving GPRS Support Node): Responsável pela localização do dispositivo móvel e roteamento dos pacotes.
• GGSN (Gateway GPRS Support Node): Interface com outras redes digitais,
como a Internet.
4.1.3
EDGE e UMTS
Estas tecnologias são evoluções do GPRS. Foram desenvolvidas com a principal
finalidade de prover maior taxa de transmissão de dados.
O EDGE (Enhanced Data rates for GSM Evolution) provê taxas de transmissão que variam entre 236,8 e 473,6 kbps, quatro vezes maior que o GPRS. O
EDGE, também chamado de EGPRS (Enhanced GPRS), trabalha de forma similar
ao GPRS, podendo coexistir em uma mesma rede. Os GSN devem ser atualizados
para incorporar as novas tecnologias de transmissão adotadas pelo EDGE, mas as
diferenças se encerram aqui. Logo, a rede pode ser atualizada gradualmente, sem
impacto no serviço já existente.
A tecnologia UMTS (Universal Mobile Telecommunications System), que faz
parte das evoluções do GSM denominadas 3G (terceira geração), promete teóricos 21 Mbps, mas por enquanto suas implementações suportam até 7.2 Mbps. A
30
Figura 4.2: Placa PCMCIA da VIVO para acesso a rede GSM 3G
migração para este padrão não é tão transparente quanto a EDGE, necessitando a
troca de várias camadas de comunicação da rede, mas ainda assim os dois modos
de transmissão ainda podem coexistir (Richardson, 2000).
4.1.4
Acesso à Internet Móvel
A evolução das tecnologias móveis foi cada vez mais aproximando os aparelhos celulares da Internet. Era só uma questão de tempo até que os aparelhos celulares
começassem a ser usados como porta de entrada a Internet por computadores portáteis.
No começo era necessário o uso de um telefone celular conectado ao computador para acesso à Internet. Este acesso era complicado, dependendo de drivers
específicos para o telefone e sistema operacional em uso (Junior, 2005).
Hoje já estão difundidos aparelhos específicos para esta ligação, os chamados
Modens 3G. São aparelho celulares simplificados, com baixo consumo de energia,
podendo ser energizados pela porta USB ou interface PCMCIA. Notebooks já estão
sendo construídos com esta interface embutida, facilitando ainda mais o acesso.
Nas figuras 4.2 e 4.3 temos exemplos de equipamentos voltados para este acesso.
Este tipo de acesso permite, além de conexão à Internet, também o envio de
SMS. Estas características satisfazem as exigências do sistema de telemetria quanto
a telecomunicações. Considerando a disponibilidade de conexão USB na Beagle Board (Seção 2.2) , esta será a interface usada para o projeto.
31
Figura 4.3: Interface USB GSM 3G.
32
Capítulo 5
Arquitetura do Sistema
Para o desenvolvimento do sistema, é necessário definir sua arquitetura. O projeto
Karmonitor define a plataforma para desenvolvimento dos sistemas embarcados.
5.1
Hardware
Por se tratar de um sistema embarcado de alta complexidade, um hardware poderoso e ao mesmo tempo portátil deve ser usado. A proposta do projeto Karmonitor
é especificar e construir um hardware customizado que será o computador a bordo
do veículo. Mas como protótipo, a equipe do projeto Karmonitor definiu como plataforma inicial de desenvolvimento do sistema uma placa de design aberto, expansível, de alta performance e baixo custo que está acolhendo uma crescente comunidade de desenvolvedores interessados, a Beagle Board.
A Beagle Board possui um processador ARM da Texas Instrument, o OMAP3530,
capaz de rodar a 600MHz com um cache L2 de 256kb e memória RAM de 256Mb.
Possui somente funcionalidades de áudio e vídeo integrados.
O poder da Beagle Board está justamente na sua falta de componentes integrados, que é compensada pela sua alta expansibilidade. Possui interface USB,
MMC+/SD/SDIO, RS-232 e J-TAG. Já existem diversos periféricos testados para
expandir as funcionalidades da Beagle Board.
Outra característica importante é o baixo consumo de energia, podendo ser alimentada pela porta USB ou por uma fonte DC de 5v, o que facilita sua instalação
em um veículo.
5.2
Sistema Operacional
O sistema operacional que será usado na Beagle Board será uma distribuição de
Linux para sistemas embarcados. A escolha deve-se a diversos motivos. Um é o
fato de ser o sistema operacional mais utilizado em conjunto com a Beagle Board.
Logo, já possui amplo suporte e documentação provido pela comunidade. Por ser
um sistema de código aberto, possibilita customizações de acordo com a necessidade
do projeto.
33
Figura 5.1: A Beagle Board com seus principais componentes destacados
Outras características do Linux que justificam a escolha é sua modularização,
que é importante para sistemas embarcados, permitindo que somente os módulos
necessários sejam carregados no kernel, economizando recursos, e o fato de ser um
sistema amplamente usado e divulgado, logo já existe muito software disponível
para o sistema.
A distribuição escolhida pela equipe é a distribuição Angstrom, especialmente
voltada para sistemas embarcados.
5.2.1
Linux
Kernel de código aberto escrito por Linus Torvalds em meados de 1991. A princípio
foi desenvolvido somente como um hobby, para ser uma alternativa ao MINIX,
escrito por Andrew Tanenbaum em 1987 como projeto acadêmico, pois tinha uma
licença muito restritiva.
34
O Linux foi desenvolvido como um kernel monolítico, que controla a execução
dos processos, acesso a rede, sistema de arquivos e periféricos. Os drivers dos
dispositivos da máquina são integrados ao kernel através de módulos.
Acabou se tornado muito popular pela comunidade e com uma equipe constante
de desenvolvedores acabou se tornando um kernel muito abrangente, suportando
diversas arquiteturas, como laptops e desktops até celulares e supercomputadores.
Vários sistemas operacionais baseados no Linux surgem a cada dia, cada qual com
suas características específicas para atender necessidades diferentes. Estes sistemas são chamados de distribuições Linux, ou distros.
5.2.2
Angstrom
O Angstrom nasceu da colaboração de integrantes de outras distribuições de Linux
voltadas para sistemas embarcados, os OpenEmbedded, OpenZaurus e OpenSIMPad. O objetivo desta comunidade é criar uma distribuição Linux especialmente
voltada para sistemas embarcados baseados em processadores ARM.
Sua principal característica é a escalabilidade, podendo ocupar meros 4Mb, ou
gigas de armazenamento. A escalabilidade é alcançada através de pacotes de software que permitem que os desenvolvedores acrescentem as funcionalidades a medida que são necessárias. O gerenciador de pacotes utilizado no Angstrom é o ipkg
(Itsy Package Management System), especialmente voltado para sistemas embarcados por ocupar pouco espaço de armazenamento. É baseado no gerenciador de
pacotes do Debian, o dpkg.
5.3
Software
Para a realização da telemetria, serão desenvolvidos e/ou empregados softwares
para realizar cada etapa do processo.
5.3.1
Medição
A primeira etapa do processo de telemetria, a medição dos dados, deve ser realizada
por um software que seja capaz de utilizar a interface serial criada pelo conector
USB x OBD, levantar os dados e armazená-los localmente.
Já existem softwares desenvolvidos com este fim, mas a maioria é composta
de software proprietário, de código fechado, e dependente de plataforma. Porém,
existe um programa que não se encaixa nesta maioria, chamado obdgpslogger, desenvolvido por Gary Briggs (Briggs, 2009).
A proposta do obdgpslogger é ser um gravador de logs de dados funcionais de
automóveis juntamente com coordenadas GPS, sendo assim possível reconstruir o
trajeto de um veículo e monitorar seus dados funcionais durante o percurso.
O obdgpslogger foi escrito na linguagem C sob a licença GPL, tendo seu código
fonte disponibilizado. Foi totalmente escrito para ser compatível com sistemas POSIX, e desenvolvido em módulos, separados por funcionalidades. Os seguintes módulos são os principais para o objetivo deste projeto, entre outros desenvolvidos.
35
• obdgpslogger: O módulo principal, responsável pela comunicação serial e gravação dos dados.
• obdsim: Simulador OBD, que possibilita testes longe de um automóvel, simulando uma porta serial ligada ao sistema OBD.
• obd2csv: Conversor dos dados gravados pelo logger para o formato CSV.
O obdgpslogger já foi implementado em diversos sistemas e arquiteturas diferentes, inclusive testes foram feitos no hardware e sistema operacional definidos
neste projeto, executando normalmente. Por atender as necessidades do projeto,
este software será usado na medição dos dados OBD do automóvel.
5.3.2
Cliente
A parte do cliente será um software que executará a bordo do veículo, no sistema
embarcado. Logo deverá ser executado em um ambiente com poucos recursos, devendo acessar os dados gerados pelo obdgpslogger, convertê-los e enviá-los pela
conexão com a Internet móvel. Considerando a arquitetura do sistema, o sucesso
da execução do obdgpslogger e a necessidade de ambos executarem simultaneamente, a parte do cliente será desenvolvida de forma semelhante, na linguagem C,
fazendo chamadas aos módulos do obdgpslogger quando necessário. As tarefas do
cliente resumem-se a:
• Verificar e estabelecer a conexão com o servidor.
• Utilizar o módulo obd2csv para fazer a conversão dos dados e salvá-los em
arquivos em local apropriado.
• Envio dos dados ao servidor.
• Limpeza dos dados medidos anteriormente após a conversão, considerando
que este é um sistema embarcado com pouco espaço para armazenamento.
Para o acesso aos dados gerados pelo obdgpslogger, será usada a mesma API de
código aberto, o SQLite, uma API que permite a criação de bancos de dados simples
e compactos.
Como parte do processo de desenvolvimento, foi desenhado um fluxograma para
facilitar a visualização do processo de execução do cliente (Figura 5.2).
O intervalo de cinco minutos entre cada envio foi definido arbitrariamente,
sendo necessários testes para verificar se o acumulo de dados neste intervalo não
será grande demais para fazer o envio, considerando a largura de banda limitada
das conexões celulares, ou se esse intervalo de tempo não é curto demais, sobrecarregando o servidor com conexões desnecessárias. Estes dados são avaliados no
capítulo 6.
O sistema prevê a indisponibilidade de conexão com o servidor, considerando a
natureza de sua conexão. O sistema somente fará a conversão dos dados quando
o servidor for contatado. Sendo assim, é possível que haja acúmulo excessivo de
dados em caso de um período muito longo de ausência de conexão (por exemplo, em
36
Figura 5.2: Fluxograma do programa cliente
37
percursos intermunicipais, longe do serviço das redes celulares). Para isso, foi feito
cálculo, considerando a taxa de medição de dados pelo obdgpslogger, sendo possível
prever o tamanho de armazenamento necessário para armazenar a quantidade de
dados gerados enquanto não se obtém uma conexão com o servidor. Estes dados
são levantados no capítulo 6.
5.3.3
Servidor
O processo servidor será um programa executando em alguma máquina conectada
a Internet, esperando pela conexão de processos clientes rodando nos veículos monitorados. Este servidor não tem limitações como o processo cliente, logo pode ser
implementado em qualquer tipo de sistema que suporte a tarefa. Considerando
a possibilidade de alto número de veículos sendo monitorados, um computador de
alta capacidade de processamento e armazenamento é recomendado. Para obter
portabilidade, usou-se a linguagem Java para o desenvolvimento do servidor, e um
banco de dados PostgreSQL para o armazenamento dos dados.
Programa
As tarefas do programa servidor:
• Receber conexões de um cliente.
• Validar se o veículo está registrado.
• Enviar parâmetros de conexão/comandos.
• Receber arquivos CSV compactados e descompactá-los.
• Ler os arquivos e armazenar os dados no banco de dados.
A figura 5.3 é um fluxograma do funcionamento do servidor. Como mostrado,
este é um programa multithread, ou seja que cria várias threads que são executadas paralelamente. Isto se deve ao fato de que ele deve ser capaz de tratar diversas
conexões simultaneamente.
Para o desenvolvimento do servidor foi utilizada, além das bibliotecas básicas
do Java, a biblioteca OpenCSV (Smith et al., 2009), biblioteca Java de código aberto
para manipulação de arquivos CSV.
O diagrama de classes para o programa pode ser visto na figura 5.4. No pacote
principal estão os processos Main, que somente realiza, a cada conexão, a criação
de thread representada pela classe ServerThread, que faz o trabalho de comunicação com o cliente através de sockets. No pacote db estão as classes responsáveis
pelo acesso ao banco de dados, os DAO (Data Access Objects), e no pacote beans
está o objeto que representa um veículo. Não foi criado objeto para representar
os dados OBD pois os dados são transferidos diretamente do arquivo CSV para o
procedimento de gravação do banco na classe ObdDao.
38
Figura 5.3: Fluxograma do programa servidor
39
Figura 5.4: Diagrama de classes do programa servidor
40
Coluna
id
license
description
Tipo
integer
character(7)
text
Obs.
Campo sequencial, chave primária
Placa do carro, chave única
Descrição, texto livre
Tabela 5.1: Estrutura da tabela de veículos
Coluna
id_vehicle
time
gps_lat
gps_lon
gps_alt
dtcfrzf
fuelsys
load_pct
temp
Tipo
integer
numeric
numeric
numeric
numeric
integer
integer
numeric(9,6)
integer
Obs.
Chave estrangeira da tabela de veículos, e chave primária.
Timestamp do momento da medição, chave primária.
Latitude GPS
Longitude GPS
Altitude GPS
...
Tabela 5.2: Estrutura parcial da tabela de dados OBD
Banco de dados
O banco de dados utilizado para o desenvolvimento é o PostgreSQL, mas nada
impede que outros bancos que suportem drivers Java JDBC sejam utilizados. O
banco é composto somente de duas tabelas, dispensando um diagrama entidade
relacionamento. As tabelas são a tabela de cadastro de veículos e a tabela de dados
OBD. Suas estruturas são mostradas respectivamente nas tabelas 5.1 e 5.2. O
script SQL de criação delas pode ser visto no anexo III.
A tabela de dados OBD possui campos para descrição de todos os dados possíveis
de serem monitorados pelo padrão OBD, como descrito na tabela 3.1, já convertidos
para o valor numérico correspondente. Mas raramente os veículos suportam todos
os campos, deixando os campos que não suporta com o valor nulo. Isto acarreta
um certo desperdício de armazenamento, que poderia ser evitado pela criação de
tabelas relacionais separadas por cada campo, e uma tabela de registro de campos
suportados por cada veículo. Isto, porém, acarretaria em uma maior necessidade
de processamento por parte do processo servidor ao receber os dados, e muito mais
acessos ao banco de dados, além de uma quantidade muito maior de tabelas no
banco de dados.
Considerando a gravação de 300 registros no banco de dados com 10 colunas, ao
invés de 300 comandos SQL para gravar as linhas, seriam necessários 300 ∗ 10 =
3000 comandos para gravação dos dados. Considerando o custo cada vez menor
para armazenamento, a economia em processamento e acesso ao banco tem impacto
muito maior do que o desperdício de armazenamento.
41
Comando
CMD_SEND_LICENSE
Objetivo
Requisita do cliente o envio da placa do carro
CMD_RECV_BUFFERSZ Avisa para o cliente receber inteiro que representa o tamanho do buffer
para troca de arquivos (B)
CMD_SEND_NUMFILES Requisita do cliente o número de arquivos que serão enviados (N )
CMD_SEND_FILES
Requisita do cliente o envio dos arquivos
CMD_RECV_SLEEPTM
CMD_BYE
Altera tempo de espera do
cliente entre as conexões.
Informa ao cliente o fim
da transmissão
Resposta
Cliente envia string de 7
caracteres
Cliente recebe inteiro
Cliente envia inteiro
Para cada arquivo, é enviado seu tamanho (T ), e
em seguida T /B pacotes
de B bytes
Cliente recebe inteiro
Conexão fechada
Tabela 5.3: Comandos que o servidor pode enviar ao cliente
5.3.4
Protocolo de comunicação
A conexão estabelecida entre o cliente o servidor é feita através de Sockets, ou seja,
utilizando o protocolo TCP sobre IP, o que significa que as mensagens são recebidas
sincronizadamente e com checagem de erro.
A comunicação entre os processos se dá na forma de comandos enviados pelo
servidor. A conexão é estabelecida pelo cliente, mas este então recebe os comandos
que são enviados do servidor. Isto permite que alterações no comportamento do
sistema sejam feitos somente pelo servidor, sendo necessário alterar o cliente somente quando se deseja adicionar uma funcionalidade. Os comandos são números
inteiros positivos definidos como constantes nos programas. A tabela 5.3 mostra
uma lista dos comandos implementados.
Quando algum erro ocorre na comunicação, ela é cortada imediatamente. Como
a conexão é feita constante e periodicamente, não existe a necessidade para tratamento e recuperação de erros. Os dados não enviados são deixados para serem
enviados na tentativa seguinte.
42
Capítulo 6
Testes e análises
Para estudar o comportamento do sistema, é necessário executar testes controlados
para averiguar as variáveis que o influenciam. Testes foram executados em alguns
automóveis de diferentes fabricantes, sendo possível levantar a diferença de dados
disponíveis para medição em cada modelo. Os automóveis foram dirigidos durantes os testes por diferentes percursos e horários, com o fim de testar o impacto da
qualidade do sinal para o envio dos dados. Porém, considerando o ambiente urbano, onde existe cobertura de sinal em quase toda área livre, pouca diferença foi
percebida neste quesito.
Outra importante consideração que deve ser feita no sistema é se o meio de
envio dos dados permite uma banda suficiente para que não haja acúmulo de dados
localmente. Considerando o meio instável de conexão e a alta taxa de medição e
a quantidade de dados levantados, esta é uma preocupação que é considerada nos
testes a seguir.
Antes de divulgar os resultados, é necessário expor os procedimentos realizados
para execução do sistema, a plataforma utilizada, que não é a mesma definida como
plataforma final de execução do projeto, e os cálculos realizados.
6.1
Plataforma de testes
O sistema foi testado utilizando-se plataforma e interfaces diferentes das pretendidas, porém semelhantes, o que não garante um resultado completo, mas é uma
boa aproximação para estimar o comportamento do sistema em funcionamento.
A plataforma de execução utilizada é um notebook Dell Latitude D520 com processador Intel e sistema operacional Ubuntu Linux versão 9.10 (Figura 6.2).
A interface com o automóvel é feita utilizando-se conector OBDxUSB comercial
baseado no ELM327 (Figura 6.3). A versão do obdgpslogger utilizada foi a versão
0.10, disponibilizada em outubro de 2009.
Para a conexão com a Internet, ao invés de modem 3G dedicado, utilizou-se
um telefone celular Nokia N95 com conexão USB. O sistema operacional Ubuntu
já possui os drivers necessários para fazê-lo funcionar como um modem 3G/GPRS
(Figura 6.4). A operadora de telefonia celular na qual o aparelho é usado é a Claro.
43
6.2
Procedimentos
Os procedimentos necessários para a criação do ambiente e realização dos testes
foram os seguintes:
• Montagem do ambiente cliente
– Compilação do obdgpslogger.
– Compilação do cliente de telemetria.
– Configuração e instalação de drivers necessários para o conector OBD.
– Conexão a Internet móvel.
• Montagem do ambiente servidor
– Compilação do servidor de telemetria.
– Instalação e configuração de banco de dados.
– Abertura de portas necessárias para comunicação.
6.2.1
Montagem do ambiente cliente
Como já dito, o ambiente de execução dos processos cliente foi feito em um notebook
rodando o Ubuntu Linux versão 9.10.
Compilação do obdgpslogger
Para compilar o fonte do programa disponibilizado em sua página da Internet (Briggs,
2009), é necessária a ferramenta CMake, que é uma ferramenta para facilitar a
compilação de programas em diferentes ambientes, possibilitando a configuração
do executável.
Através do comando CCMake é possível customizar a compilação, removendo
módulos desnecessários como os módulos de interface que acompanham o obdgpslogger, além de alterar alguns valores padrões para o programa, como caminho de
destino do arquivo de log e porta serial padrão do dispositivo OBD.
As bibliotecas necessárias para compilação são as pthread e dl, usadas pelo
código do SQLite, incluso com o fonte do programa.
Para o uso dos recursos GPS do programa, é necessária a instalação do gpsd,
aplicativo de interface com dispositivos GPS.
Compilação do cliente de telemetria
O cliente de telemetria pode ser compilado com o uso do GCC, compilador C padrão
nos sistemas GNU/Linux. Além das bibliotecas citadas acima para uso do SQLite,
é necessária a biblioteca libconfig para leitura de arquivo de configuração que deve
ser gerado em /etc/obdtelemetry.cfg com os parâmetros do cliente. Exemplo de arquivo de configuração pode ser visto na figura 6.1. As variáveis são:
• hostname: Nome ou IP do servidor
44
/∗
# Configuration f i l e f o r o b d t e l e m e t r y c l i e n t
∗/
hostname = " hostname . ath . cx " ;
v e h i c l e _ i d = "NEW1234 " ;
db_path = " / home / a l c i d e s / obdlogs / obd . db " ;
Figura 6.1: Exemplo de arquivo de configuração do cliente
• vehicle_id: Placa do carro sendo medido
• db_path: Caminho do arquivo que está sendo gerado pelo obdgpslogger
Instalação de drivers necessários para o conector OBD
A comunicação com as interfaces OBD baseadas no ELM327 é feita através de
porta serial. Se o adaptador usado for de conexão RS-232, não é necessário nenhum
driver. Porém, se for utilizada outra interface, como a USB, é necessário que seja
feita a instalação do driver do conversor de sinal USBxRS-232 utilizado no conector.
Nos testes o conector utilizado possuía interface USB serial com chip FTDI. Os
drivers já estavam instalados no Ubuntu.
Depois que o dispositivo é reconhecido pelo sistema, é necessário configurar sua
taxa de transmissão (baud rate) para que a comunicação serial ocorra. Esta taxa
depende do dispositivo sendo usado e pode não ser detectada automaticamente. No
dispositivo usado, a taxa era erroneamente detectada como 9200 bauds sendo que
o valor correto era 38400.
Conexão a Internet móvel
Para conectar o sistema a Internet móvel, é necessário um modem ou telefone com
interface para conexão de computadores à rede GSM. O telefone utilizado, o Nokia N95, foi detectado automaticamente pelo Ubuntu e foi possível fazer conexão
através de sua interface.
6.2.2
Montagem do ambiente servidor
O computador utilizado como servidor nos testes foi um desktop com processador
AMD e sistema Windows, mas nada no programa servidor impede que seja usado
outra arquitetura, já que ele foi desenvolvido em Java.
45
Compilação do servidor de telemetria
Para o desenvolvimento e compilação do programa servidor, foi utilizado o Java
SE versão 1.6.0.15. Além das bibliotecas padrões do Java, foi utilizada a biblioteca OpenCSV (Smith et al., 2009) e a biblioteca de conexão com o banco de dados
PostgreSQL.
Instalação e configuração de banco de dados
Para a instalação e configuração do banco de dados foi instalado pacote contendo
o banco de dados e ferramentas de administração conhecido como PostgreSQL EnterpriseDB, disponível gratuitamente na Internet.
Foram criadas duas tabelas no banco, como mostram os scripts SQL no anexo III.
Registros de veículos são adicionados manualmente através de ferramenta de administração do banco.
Abertura de portas necessárias para comunicação
A porta IP definida para comunicação entre os processos é a 22490. O servidor
deve estar conectado a Internet e com esta porta aberta para que a conexão funcione. Se houver roteamento e NAT, o gateway deve ser configurado para direcionar
requisições desta porta para a máquina servidora.
6.3
Cálculos
Alguns simples cálculos são feitos para averiguar o comportamento e viabilidade do
sistema, para assegurar que o acúmulo indefinido de dados não ocorra facilmente.
Variáveis medidas durante os testes:
• Tt (Taxa de Transmissão média observada, em kb/s)
• Tc (Taxa de Crescimento dos dados em kb/s)
Tt é medido dividindo o tamanho do arquivo enviado pelo tempo de envio. Tc é
calculado observando-se o tamanho dos arquivos gerados pelo sistema.
Vamos definir λ como o intervalo de tempo, em segundos, entre uma conexão e
outra do sistema. A princípio escolhemos λ = 300. Os arquivos a serem enviados
são gerados neste intervalo de tempo.
Chamamos de dt o tamanho em kbytes dos dados levantados no intervalo de t
segundos. Podemos calcular o valor de Tc através de dλ da seguinte forma:
Tc =
dλ
λ
Para verificarmos a viabilidade do sistema, calculamos o tempo necessário para
envio dos dados levantados durante t segundos (Tempo de Esvaziamento em t, τt ):
τt =
dt
Tc
=
×t
Tt
Tt
46
Indiscutivelmente, se Tc > Tt , o sistema é inviável já que nunca será possível
enviar mais dados do que são gerados. Se Tc = Tt , a cada erro e falha de conexão
haverá acúmulo de dados que nunca serão enviados. Logo para o sistema ser viável
deve acontecer que Tc < Tt .
Mesmo com Tc < Tt , um tempo muito grande sem conexão ou muitas falhas
consecutivas poderiam gerar um acúmulo de dados que demoraria muito tempo
para ser desfeito. Mesmo havendo conectividade, durante o envio ainda haveria
acúmulo. Porém, como vamos observar nos testes a seguir, Tt Tc , logo τt t.
Ou seja, qualquer acúmulo é rapidamente desfeito no momento em que ocorre uma
conexão devido a grande diferença entre a taxa de transmissão e de acúmulo de
dados.
6.4
6.4.1
Ford Ka 1.0 2009
Dados do teste
• Data: 23 de Novembro de 2009
• Percurso: SQN 214 até Esplanada dos Ministérios, via Setor de Clubes
Norte, Brasília.
• Duração: 13:34 às 14:11 (37 minutos)
• Quantidade de registros gerados: 2198
6.4.2
Campos OBD suportados
De acordo com a tabela 3.1.
Campo
load_pct
temp
shrtft13
longft13
map
rpm
vss
sparkadv
iat
throttlepos
obdsup
mil_dist
Descrição
Calculated LOAD Value
Engine Coolant Temperature
Short Term Fuel Trim - Bank 1,3
Long Term Fuel Trim - Bank 1,3
Intake Manifold Absolute Pressure
Engine RPM
Vehicle Speed Sensor
Ignition Timing Advance for Cylinder 1
Intake Air Temperature
Absolute Throttle Position
OBD requirements to which vehicle is designed
Distance Travelled While MIL is Activated
Tabela 6.1: Dados OBD suportados pelo Ford Ka.
47
6.4.3
Valores observados
Na tabela 6.2 estão as variáveis funcionais calculadas durante os testes. Na tabela 6.3 estão alguns exemplos dos dados levantados. Com os dados levantados
foi possível calcular o valor médio de alguns dos parâmetros, como mostrado na
tabela 6.4
Variável
Valor
Tt
2,44 kb/s
Tc
0,28 kb/s
τ300
34s
τ3600
413s
Tabela 6.2: Taxas do sistema observadas durante testes no Ford Ka.
temp map
93
84
93
86
93
79
93
77
93
86
94
84
94
85
94
33
94
80
94
77
94
34
94
35
94
36
94
36
94
35
94
38
94
58
94
54
94
52
94
57
94
85
rpm
vss iat throttlepos
time
1274.00
0
54
24.313726
1258990717.951405
1642.00
8
54
37.647060
1258990718.951953
2285.00 13 54
0.000000
1258990719.952505
1646.00 14 54
25.882353
1258990720.953055
1632.00 16 54
33.333332
1258990721.953610
1934.00 20 54
33.725491
1258990722.954153
2192.00 23 54
37.254902
1258990723.954700
1958.00 25 53
5.882353
1258990724.955245
1555.00 25 54
20.784313
1258990725.955788
1674.00 27 54
1.176471
1258990726.956316
1651.00 27 53
0.000000
1258990727.956830
1571.00 26 53
0.000000
1258990728.957370
1529.00 25 54
0.000000
1258990729.957945
1447.00 24 54
0.000000
1258990730.958516
1326.00 22 54
0.000000
1258990731.959079
1197.00 20 54
0.000000
1258990732.959635
937.00
18 54
0.000000
1258990733.960249
993.00
15 54
0.000000
1258990734.960792
981.00
11 54
0.000000
1258990735.961345
927.00
10 54
8.235294
1258990736.961903
1081.00 11 55
29.411764
1258990737.962447
Tabela 6.3: Exemplo de dados levantados para o Ford Ka.
6.5
6.5.1
Nissan Livina 1.6 2009
Dados do teste
• Data: 28 de Novembro de 2009
48
Parâmetro Média
temp
91.6
map
59
rpm
1920
vss
39
throttlepos
14.64
Tabela 6.4: Valores médios de parâmetros levantados para o Ford Ka.
• Percurso: SQS 316 até CLS 207, via Eixo W, Brasília.
• Duração: 20:32 às 20:40 (8 minutos)
• Quantidade de registros gerados: 456
6.5.2
Campos OBD suportados
De acordo com a tabela 3.1.
Campo
load_pct
temp
shrtft13
longft13
map
rpm
vss
sparkadv
iat
throttlepos
o2sloc
o2s11
o2s12
obdsup
mil_dist
Descrição
Calculated LOAD Value
Engine Coolant Temperature
Short Term Fuel Trim - Bank 1,3
Long Term Fuel Trim - Bank 1,3
Intake Manifold Absolute Pressure
Engine RPM
Vehicle Speed Sensor
Ignition Timing Advance for Cylinder 1
Intake Air Temperature
Absolute Throttle Position
Location of Oxygen Sensors
Bank 1 - Sensor 1/Bank 1 - Sensor 1 Oxygen Sensor
Output Voltage / Short Term Fuel Trim
Bank 1 - Sensor 2/Bank 1 - Sensor 2 Oxygen Sensor
Output Voltage / Short Term Fuel Trim
OBD requirements to which vehicle is designed
Distance Travelled While MIL is Activated
Tabela 6.5: Dados OBD suportados pelo Nissan Livina.
6.5.3
Valores observados
Na tabela 6.6 estão as variáveis funcionais calculadas durante os testes. Na tabela 6.7 estão alguns exemplos dos dados levantados. Com os dados levantados
foi possível calcular o valor médio de alguns dos parâmetros, como mostrado na
tabela 6.8
49
Variável
Valor
Tt
1,86 kb/s
Tc
0,28 kb/s
τ300
45s
τ3600
541s
Tabela 6.6: Taxas do sistema observadas durante testes no Nissan Livina.
temp map
88
31
88
31
88
30
89
31
89
29
89
31
89
29
89
29
89
29
89
29
89
30
89
31
89
31
90
32
89
32
90
32
90
31
90
46
90
44
rpm
vss iat throttlepos
time
792.00
8
39
11.764706
1259451323.655444
809.00
8
39
11.764706
1259451324.656021
799.00
3
39
11.764706
1259451325.656564
796.00
0
39
11.764706
1259451326.657070
804.00
0
39
12.549020
1259451327.657567
826.00
0
39
11.764706
1259451328.658065
826.00
0
39
11.764706
1259451329.658566
800.00
0
39
11.764706
1259451330.659066
795.00
0
39
11.764706
1259451331.659568
764.00
0
39
11.764706
1259451332.660063
739.00
0
39
11.764706
1259451333.660566
741.00
0
39
11.764706
1259451334.661068
741.00
0
39
11.764706
1259451335.661571
721.00
0
39
11.764706
1259451336.662092
740.00
0
39
11.764706
1259451337.662575
744.00
0
39
11.764706
1259451338.663067
756.00
0
39
15.294118
1259451339.663568
2376.00
2
39
18.823530
1259451340.664068
2321.00
5
39
18.823530
1259451341.664567
Tabela 6.7: Exemplo de dados levantados para o Nissan Livina.
6.6
6.6.1
Ford Focus 2.0 2009
Dados do teste
• Data: 25 de Novembro de 2009
• Percurso: 214 Norte até 506 Norte, ida via W3, volta via Eixo L.
• Duração: 22:29 às 23:30 (61 minutos)
• Quantidade de registros gerados: 3386
6.6.2
Campos OBD suportados
De acordo com a tabela 3.1.
50
Parâmetro Média
temp
88
map
36
rpm
1550
vss
42
throttlepos
14.85
Tabela 6.8: Valores médios de parâmetros levantados para o Nissan Livina.
Campo
load_pct
temp
rpm
vss
obdsup
mil_dist
aat
Descrição
Calculated LOAD Value
Engine Coolant Temperature
Engine RPM
Vehicle Speed Sensor
OBD requirements to which vehicle is designed
Distance Travelled While MIL is Activated
Ambient Air Temperature
Tabela 6.9: Dados OBD suportados pelo Ford Focus.
6.6.3
Valores observados
Na tabela 6.10 estão as variáveis funcionais calculadas durante os testes. Na tabela 6.11 estão alguns exemplos dos dados levantados. Com os dados levantados
foi possível calcular o valor médio de alguns dos parâmetros, como mostrado na
tabela 6.12
Variável
Valor
Tt
1,71 kb/s
Tc
0,14 kb/s
τ300
24s
τ3600
294s
Tabela 6.10: Taxas do sistema observadas durante testes no Ford Focus.
51
temp
92
92
92
93
92
92
92
92
92
92
92
92
92
92
92
92
93
93
93
92
rpm
vss
time
1537.75
7
1259199063.590389
1886.50 13 1259199064.590835
2245.25 19 1259199065.591290
2437.75 24 1259199066.591753
2109.75 29 1259199067.592208
1979.75 32 1259199068.592670
1767.25 32 1259199069.593141
1167.75 32 1259199070.593585
1141.00 30 1259199071.594017
1071.50 28 1259199072.594504
1001.75 26 1259199073.594989
966.25
24 1259199074.595407
904.50
23 1259199075.595919
941.75
22 1259199076.596382
1695.25 22 1259199077.596854
2178.25 25 1259199078.597337
2197.00 28 1259199079.597804
2215.50 30 1259199080.598287
2117.50 32 1259199081.598769
2047.50 32 1259199082.599231
Tabela 6.11: Exemplo de dados levantados para o Ford Focus.
Parâmetro Média
temp
94
rpm
855
vss
14
Tabela 6.12: Valores médios de parâmetros levantados para o Ford Focus.
52
Figura 6.2: Notebook Dell utilizado para executar o sistema
Figura 6.3: Conector USBxOBD
53
Figura 6.4: Celular Nokia N95 com cabo USB para uso como modem 3G/GPRS.
Figura 6.5: Automóvel Ford Ka 1.0, ano 2009, exterior.
54
Figura 6.6: Localização do conector OBD no Ford Ka.
Figura 6.7: Automóvel Nissan Livina 1.6, ano 2009, exterior.
55
Figura 6.8: Localização do conector OBD no Nissan Livina.
Figura 6.9: Automóvel Ford Focus 2.0, ano 2009, exterior.
56
Figura 6.10: Localização do conector OBD no Ford Focus.
57
Capítulo 7
Conclusão e desenvolvimentos
futuros
Através deste trabalho foi possível verificar que a tecnologia existente hoje em dia,
tanto em questões de software, como hardware e infra-estrutura em telecomunicações, permitiram o desenvolvimento de sistema de telemetria para veículos automotores. Todos os objetivos do projeto foram alcançados, porém sua integração ao
sistema Karmonitor ainda necessita de alguns passos.
Primeiramente, em questão ao hardware, o conector OBD e os softwares utilizados neste projeto foram testados sob o Angstrom na Beagle Board e funcionaram.
Porém não foi possível realizar os testes de uso neste hardware pois não foi feita
ainda a instalação da placa em um automóvel. Logo o ambiente de hardware utilizado nos testes foi diferente. Isto pode levar a diferenças com relação a performance
do sistema, visto que a Beagle Board é um ambiente mais limitado que o notebook
utilizado. Para a integração deste sistema na Beagle Board, é necessário:
• Compilação dos programas clientes para execução no Angstrom da Beagle Board (Já comprovado ser possível).
• Instalação do driver necessário para a interface USBxSerial utilizada no conector OBD desejado. (O conector utilizado neste projeto já foi testado com
sucesso na Beagle).
• Instalação de drivers e componentes do sistema para conexão à Internet pela
rede celular.
• Instalação da Beagle em um automóvel.
Com relação ao software, como o programa cliente estará executando em um
computador a bordo, é necessário que ele e o obdgpslogger sejam configurados para
funcionarem como daemons, executando automaticamente com o boot do sistema
operacional.
Outro aspecto que não foi abordado e que é fundamental para o uso do sistema
em larga escala é a questão da segurança. Os dados devem ser assinados e/ou criptografados para evitar interferências e interceptações por terceiros, considerando
58
que estes dados trafegarão em rede pública, a Internet. Uma simples implementação de criptografia, tanto simétrica como assimétrica, deve ser o suficiente para
sanar a vulnerabilidade.
Uma capacidade do obdgpslogger que não foi explorada é a de monitoramento
da posição através de dispositivo GPS ligado ao computador que executa o cliente.
Porém, o cliente já está preparado para enviar os dados, basta que um equipamento
compatível com o programa gpsd esteja conectado. Esta funcionalidade só não foi
explorada por falta do hardware adequado para testes.
Outra possibilidade para o sistema é sua especialização quanto a veículos e fabricantes. Através da porta OBD estão sendo somente levantados dados padrões
que são disponibilizados em diversos carros. Porém, através da porta OBD é possível enviar comandos e levantar dados específicos ao modelo de carro e fabricante.
Para isso, seria necessário um dispositivo USB x OBD diferenciado, pois o ELM327
somente suporta os comandos padrões. Também seria necessário um patrocínio
ou parceria com a fabricante, pois tais comandos e modos de comunicação não são
publicados abertamente.
59
Referências
Anatel (2009). Total de acessos móveis pré-pago e pós-pago por uf. 28
BRASIL (1993). Lei 8.723, de 28 de outubro de 1993. publicada no diário oficial da
união em 29 de outubro de 1993. 2
Briggs, G. (2009). Obd gps logger. http://icculus.org/obdgpslogger/. Acessado em 11/2009. 35, 44
CONAMA (2006). InstruÇÃo normativa nř 126, de 24 outubro de 2006. 20
Dzhelekarski, P. and Alexiev, D. (2005a). Initializing communication to vehicle
obdii system. ELECTRONICS’05. 21
Dzhelekarski, P. and Alexiev, D. (2005b). Reading and interpreting diagnostic data
from vehicle obdii system. ELECTRONICS’05. 12, 22
ELM Electronics (2009). ELM327 - OBD to RS232 Interpreter. 23
FlexRay Consortium (2005). FlexRay Protocol Especification, 2.1a edition. 18
GSM Association (2009). Market data summary. 28
Gutierrez, E. M. (2006). Telemetria: Aplicação de rede de sensores biomédicos sem
fio. Master’s thesis, UnB - Universidade de Brasília. 3
Jenkins, W. (2004). Real-time vehicle performance monitoring using wireless
networking. Technical report, Human and Systems Engineering, Center for
Advanced Vehicular Systems, Mississippi State University, 200 Research Blvd.,
Mississippi State, Mississippi 39759, USA. 5
Junior, M. H. (2005). Internet móvel, gprs aplicado ao acesso à internet. Technical
report, Universidade Federal de Santa Catarina. viii, 30, 31
Khan, N., Saleem, Z., and Hoong, C. C. (2007). An experiment on internet based
telemetry. Proceedings of the 6th WSEAS Int. Conf. on Electronics, Hardware,
Wireless and Optical Communications, pages 68–78. 4
Kopetz, H., Elmenreich, W., and Mack, C. (2000). A comparison of lin and ttp/a. Technical report, Institut für Technische Informatik, Technische Universität Wien,
Austria. 8
60
Kopetz, H. and Grunstidl, G. (1993). Ttp - a time-triggered protocol for faulttolerant real-timesystems. In Fault-Tolerant Computing 1993, Digest of papers.,
pages 524–533. 8, 17
Kvaser AB (2009). The can protocol tour: http://www.kvaser.com/can/
protocol/index.htm, acessado em 04/2009. 12
Leen, G. and Heffernan, D. (2002). Expanding automotive electronic systems. Computer, 35(1):88–93. 7
Leen, G., Heffernan, D., and Dunne, A. (1999). Digital networks in the automotive
vehicle. Computing and Control Engineering Journal, 10(6):257–266. 7
Mantovani, J. E. and Santos, J. E. (2001). Telemetria convencional e via satélite na
determinação da área de vida de três espécies de carnívoros da região nordeste
do estado de são paulo. Master’s thesis, Universidade Federal de Santa Catarina
- UFSC. 3
MOST Cooperation (2008). MOST Specification, rev 3.0 edition. 17
Navet, N., Song, Y., Simonot-lion, F., and Wilmert, C. (2005). Trends in automotive
communication systems. Proceedings of the IEEE, 93(6):1204–1223. 6
Oliver, D. J. (2001). Implementing the J1850 Protocol. Intel Corporation. 8
Paim, F. C. A. (2005). Desenvolvimento de um sistema de telemetria para aquisiÇÃo de sinais fisiolÓgicos com aplicaÇÃo em programas de reabilitaÇÃo cardÍaca. Master’s thesis, Universidade Federal de Santa Catarina - UFSC. 3
Pazul, K. (1999). Controller area network (can) basics. Technical report, Microchip
Technology Inc. 12, 16
Peersman, G. and Cvetkovic, S. (2000). The global system for mobile communications short message service. IEEE Personal Communications. 29
Richardson, K. W. (2000). Umts overview. ELECTRONICS & COMMUNICATION
ENGINEERING JOURNAL, pages 93–101. 31
Riley, M. (1998). Computer networks take to the road. Evaluation Engineering. ix,
8, 9, 10, 11, 12
Schofield, M. J. (1996).
Controller area network (canbus):
mjschofield.com/, acessado em 04/2009. 12, 13, 16
http://www.
Scourias, J. (1997). Overview of the global system for mobile communications.
Technical report, University of Waterloo. 29
Sidorenko, A. (2009). Obd2 elm327 compatible allpro adapter with usb http://
obddiag.net acessado em 06/2009. 23
Smith, G., Sullivan, S., and Conway, S. (2009). Opencsv. http://opencsv.
sourceforge.net/. Acessado em 11/2009. 38, 46
61
TTA Group (2004). TTP - Easy to read. 8, 17
Walker, B. (2007). Augmenting amusement rides with telemetry. Advancements in
Computer Entertainment Technology, pages 115–122. 4
62
Anexo I
Código-fonte do cliente
I.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
clientmain.h
/∗
∗∗ CLIENTMAIN.H
∗ Author : A l c i d e s Carlos de Moraes Neto
∗ This f i l e i s part o f o b d t e l e m e t r y c l i e n t
∗/
#ifndef _CLIENTMAIN_H
#define _CLIENTMAIN_H
#define CSV_PATH " / tmp / obdlogs / "
//Server commands//
#define CMD_SEND_LICENSE 1
#define CMD_RECV_BUFFERSZ 2
#define CMD_SEND_NUMFILES 3
#define CMD_SEND_FILES 4
#define CMD_RECV_SLEEPTM 5
#define CMD_BYE 99
#include <sys / d i r . h>
// g e t c u r r e n t time from g e t t i m e o f d a y ( )
double get_curr_time ( ) ;
// c a l l obd2csv and g e n e r a t e csv f i l e in CSV_PATH
// The f i l e name w i l l be obd + curr_time + . csv . gz
int gen_obd_csv ( char∗ db_path , double curr_time ) ;
// used in scandir c a l l t o g e t . csv . gz f i l e s only .
63
30 int c s v g z _ f i l t e r ( const struct d i r e n t ∗ f i l e ) ;
31
32 #endif /∗ _CLIENTMAIN_H ∗/
I.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
clientmain.c
/∗
∗∗ CLIENTMAIN.C
∗ Author : A l c i d e s Carlos de Moraes Neto
∗ This f i l e i s part o f o b d t e l e m e t r y c l i e n t
∗/
#include " clientmain . h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
< s t d i o . h>
< s t d l i b . h>
<unistd . h>
<errno . h>
< s t r i n g . h>
<sys / types . h>
<sys / s t a t . h>
<sys / d i r . h>
<sys / param . h>
< l i b c o n f i g . h>
#include " networking . h"
#include " database . h"
int main ( int argc , char ∗ argv [ ] )
{
// l i b c o n f i g s t r u c t s
config_t conf ;
// I n t e r n e t s o c k e t d e s c r i p t o r
int sockfd ;
//Hostname
char ∗hostname ;
//Command r e c e i v e d from s e r v e r
char cmd ;
// V e h i c l e id
char ∗ c a r _ i d ;
// l o g g e r s q l i t e db path
char ∗ db_path ;
64
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Current time o f c o n n e c t i o n
double curr_time ;
//Number o f csv f i l e s generated and not s e n t
int f i l e c o u n t ;
// L i s t o f f i l e s t o be s e n t
struct d i r e n t ∗∗ f i l e s ;
// Full path t o a f i l e
char f i l e _ p a t h [MAXPATHLEN] ;
//FILE being s e n t
FILE ∗ f ;
// Size o f b u f f e r t o use f o r sending f i l e s . Received
from s e r v e r .
int buflen ;
// Time in seconds the program s l e e p s b e f o r e c o n n e c t i n g
to server .
// This can be changed by the s e r v e r .
int sleep_time = 300;
// Your everyday FOR counter
int i ;
i f ( mkdir (CSV_PATH, 0700) && errno != EEXIST) {
f p r i n t f ( stderr , " Error : Could not c r e a t e d i r e c t o r y %s
\n " , CSV_PATH) ;
exit (1) ;
}
errno =0;
//Loading values from c o n f i g f i l e / e t c /o b d t e l e m e t r y . c f g
c o n f i g _ i n i t (& c o n f ) ;
i f ( c o n f i g _ r e a d _ f i l e (& conf , " / e t c / obdtelemetry . c f g " ) ==
CONFIG_FALSE) {
f p r i n t f ( stderr , " Error , could not read c o n f i g f i l e : %
s\n" , c o n f i g _ e r r o r _ t e x t (& c o n f ) ) ;
exit (1) ;
}
i f ( c o n f i g _ l o o k u p _ s t r i n g (& conf , " hostname " , &hostname )
== CONFIG_FALSE) {
f p r i n t f ( stderr , " Error , could not read hostname : %s\n
" , c o n f i g _ e r r o r _ t e x t (& c o n f ) ) ;
exit (1) ;
}
i f ( c o n f i g _ l o o k u p _ s t r i n g (& conf , " v e h i c l e _ i d " , &c a r _ i d )
== CONFIG_FALSE) {
65
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
f p r i n t f ( stderr , " Error , could not read v e h i c l e _ i d : %s
\n " , c o n f i g _ e r r o r _ t e x t (& c o n f ) ) ;
exit (1) ;
}
i f ( c o n f i g _ l o o k u p _ s t r i n g (& conf , " db_path " , &db_path ) ==
CONFIG_FALSE) {
f p r i n t f ( stderr , " Error , could not read db_path : %s\n"
, c o n f i g _ e r r o r _ t e x t (& c o n f ) ) ;
exit (1) ;
}
do {
i f ( ( curr_time = get_curr_time ( ) ) < 0 ) {
f p r i n t f ( stderr , " Error : Could not get time o f
day . " ) ;
c l o s e ( sockfd ) ;
exit (1) ;
}
i f ( gen_obd_csv ( db_path , curr_time ) ) {
f p r i n t f ( stderr , " Error : Could not generate csv " )
;
c l o s e ( sockfd ) ;
exit (1) ;
}
i f ( flush_db ( db_path , curr_time ) ) {
f p r i n t f ( stderr , " Error : Could not f l u s h database
.");
c l o s e ( sockfd ) ;
exit (1) ;
}
f i l e c o u n t = scandir (CSV_PATH, &f i l e s , c s v g z _ f i l t e r ,
alphasort ) ;
i f ( f i l e c o u n t <= 0 ) {
f p r i n t f ( stderr , " Error : Could not f i n d csv f i l e (
s) . ") ;
c l o s e ( sockfd ) ;
continue ;
}
p r i n t f ( " Connecting t o %s . . . \ n" , hostname ) ;
66
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
i f ( c o n n e c ts o c k e t ( hostname , &sockfd ) < 0 ) {
p r i n t f ( " Could not c o n t a c t s e r v e r . . . \ n" ) ;
continue ; //return −1; // Could not c o n t a c t
server
}
do {
// R e c e i v e command from s e r v e r and e x e c u t e //
p r i n t f ( " Receiving command . . . " ) ;
i f ( recv_chk ( sockfd , &cmd , sizeof ( char ) , 0 ) < 0 )
{
c l o s e ( sockfd ) ;
continue ;
}
//cmd = ntohl (cmd) ;
p r i n t f ( " r e c e i v e d : %d\n" , cmd ) ;
switch ( cmd ) {
case CMD_SEND_LICENSE:
//send car l i c e n s e
i f ( send_chk ( sockfd , car_id , s t r l e n (
car_id ) , 0) < 0) {
c l o s e ( sockfd ) ;
continue ;
}
break ;
case CMD_RECV_BUFFERSZ:
// r e c e i v e b u f f e r s i z e
p r i n t f ( " r e c e i v i n g buflen . . . " ) ;
i f ( recv_chk ( sockfd , &buflen , sizeof ( int
) , 0) < 0) {
c l o s e ( sockfd ) ;
continue ;
}
buflen = ntohl ( buflen ) ;
p r i n t f ( " r e c e i v e d : %d\n" , buflen ) ;
break ;
case CMD_SEND_NUMFILES:
//send number o f f i l e s
f i l e c o u n t = htonl ( f i l e c o u n t ) ;
i f ( send_chk ( sockfd , &f i l e c o u n t , sizeof (
int ) , 0 ) < 0 ) {
c l o s e ( sockfd ) ;
continue ;
67
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
}
f i l e c o u n t = ntohl ( f i l e c o u n t ) ;
break ;
case CMD_SEND_FILES:
for ( i = f i l e c o u n t −1; i >= 0 ; i −−) {
// Going from newest t o o l d e s t
// Newer data i s more important
s t r c p y ( f i l e _ p a t h , CSV_PATH) ;
s t r c a t ( f i l e _ p a t h , f i l e s [ i ]−>d_name ) ;
f = fopen ( f i l e _ p a t h , " rb " ) ;
i f ( f == NULL) {
f p r i n t f ( stderr , " Error : Could
not open f i l e %s " , f i l e _ p a t h )
;
c l o s e ( sockfd ) ;
exit (1) ;
}
p r i n t f ( " Sending f i l e %s . . . \ n" ,
file_path ) ;
i f ( s e n d _ f i l e ( f , sockfd , buflen ) ) {
// F i l e not s e n t . . . g i v e up and
try later
fclose ( f ) ;
break ;
}
fclose ( f ) ;
i f ( remove ( f i l e _ p a t h ) ) {
f p r i n t f ( stderr , " Error : Could
not remove f i l e %s " ,
file_path ) ;
c l o s e ( sockfd ) ;
exit (1) ;
}
}
break ;
case CMD_RECV_SLEEPTM:
// r e c e i v e s l e e p _ t i m e
p r i n t f ( " r e c e i v i n g sleep_time . . . " ) ;
i f ( recv_chk ( sockfd , &sleep_time , sizeof
( int ) , 0 ) < 0 ) {
c l o s e ( sockfd ) ;
continue ;
}
sleep_time = ntohl ( sleep_time ) ;
68
184
p r i n t f ( " r e c e i v e d : %d\n" , sleep_time ) ;
185
break ;
186
case CMD_BYE:
187
default :
188
cmd=−1;
189
c l o s e ( sockfd ) ;
190
break ;
191
}
192
} while ( cmd > 0 ) ;
193
} while ( ! s l e e p ( sleep_time ) ) ;
194
195
return 0 ;
196 }
197
198 double get_curr_time ( ) {
199
struct timeval currtime ;
200
201
i f ( 0 != gettimeofday (&currtime ,NULL) ) {
202
perror ( " Error on gettimeofday " ) ;
203
return −1;
204
}
205
return ( double ) currtime . t v _ s e c +(double ) currtime . tv_usec
/1000000.0 f ;
206 }
207
208 int gen_obd_csv ( char∗ db_path , double curr_time ) {
209
// obd2csv c a l l s t r i n g
210
char o b d 2 c s v _ c a l l [ 5 1 2 ] ;
211
// f i l e name
212
char csv_filename [ 2 8 ] ;
213
214
// F i l e name
215
s p r i n t f ( csv_filename , " obd%−11.5 f . csv . gz " , curr_time ) ;
216
//obd2csv c a l l
217
s p r i n t f ( o b d 2 c s v _ c a l l , " obd2csv −d %s −z −o %s%s −e
%−11.5 f " , db_path , CSV_PATH, csv_filename , curr_time )
;
218
p r i n t f ( " obd2csv c a l l : %s\n" , o b d 2 c s v _ c a l l ) ;
219
220
i f ( system ( o b d 2 c s v _ c a l l ) ) {
221
perror ( " Error on obd2csv c a l l . " ) ;
222
return 1 ;
223
}
224
return 0 ;
69
225 }
226
227 int c s v g z _ f i l t e r ( const struct d i r e n t ∗ f i l e ) {
228
return s t r s t r ( f i l e −>d_name , " . csv . gz " ) ;
229 } ;
I.3
database.h
1 /∗ Copyright 2009 Gary Briggs
2
3 This f i l e i s part o f obdgpslogger .
4
5 obdgpslogger i s f r e e s o f t w a r e : you can r e d i s t r i b u t e i t and/
or modify
6 i t under the terms o f the GNU General Public L i c e n s e as
published by
7 the Free Software Foundation , e i t h e r v e r s i o n 2 o f the
License , or
8 ( at your o p t i o n ) any l a t e r v e r s i o n .
9
10 obdgpslogger i s d i s t r i b u t e d in the hope t h a t i t w i l l be
useful ,
11 but WITHOUT ANY WARRANTY; without even the implied warranty
of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the
13 GNU General Public L i c e n s e f o r more d e t a i l s .
14
15 You should have r e c e i v e d a copy o f the GNU General Public
License
16 along with obdgpslogger .
I f not , s e e <h t t p ://www. gnu . org/
l i c e n s e s / >.
17 ∗/
18
19
20 /∗∗ \ f i l e
21
\ b r i e f Database open and c l o s e f u n c t i o n s
22 ∗/
23 #ifndef __DATABASE_H
24 #define __DATABASE_H
25
26 #include " s q l i t e 3 . h"
70
27
28
29
30
31
32
33
34
/// Open the s q l i t e database
s q l i t e 3 ∗opendb ( const char ∗ dbfilename ) ;
/// Close the s q l i t e database
void c l o s e d b ( s q l i t e 3 ∗db ) ;
/// D e l e t e a l l rows in obd , gps and t r i p t a b l e s s t o r e d
b e f o r e endtime .
35 int flush_db ( char∗ db_path , const double endtime ) ;
36
37 #endif //__DATABASE_H
I.4
database.c
1 /∗ Copyright 2009 Gary Briggs
2
3 This f i l e i s part o f obdgpslogger .
4
5 obdgpslogger i s f r e e s o f t w a r e : you can r e d i s t r i b u t e i t and/
or modify
6 i t under the terms o f the GNU General Public L i c e n s e as
published by
7 the Free Software Foundation , e i t h e r v e r s i o n 2 o f the
License , or
8 ( at your o p t i o n ) any l a t e r v e r s i o n .
9
10 obdgpslogger i s d i s t r i b u t e d in the hope t h a t i t w i l l be
useful ,
11 but WITHOUT ANY WARRANTY; without even the implied warranty
of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the
13 GNU General Public L i c e n s e f o r more d e t a i l s .
14
15 You should have r e c e i v e d a copy o f the GNU General Public
License
16 along with obdgpslogger .
I f not , s e e <h t t p ://www. gnu . org/
l i c e n s e s / >.
17 ∗/
18
19
71
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/∗∗ \ f i l e
\ b r i e f database s t u f f
∗/
#include " database . h"
#include " s q l i t e 3 . h"
#include < s t d i o . h>
#include < s t d l i b . h>
#include < s t r i n g . h>
s q l i t e 3 ∗opendb ( const char ∗ dbfilename ) {
// s q l i t e database
s q l i t e 3 ∗db ;
// s q l i t e return s t a t u s
int r c ;
r c = s q l i t e 3 _ o p e n ( dbfilename , &db ) ;
i f ( SQLITE_OK != r c ) {
f p r i n t f ( stderr , " Error : Cannot open database
%s : %s\n" , dbfilename , s q l i t e 3 _ e r r m s g ( db
));
s q l i t e 3 _ c l o s e ( db ) ;
return NULL;
}
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Just a l i t t l e timeout t o g i v e s q l i t e a chance
//
t o f i x t h i n g s i f someone ’ s scraping the
database
s q l i t e 3 _ b u s y _ t i m e o u t ( db , 1 ) ;
return db ;
}
void c l o s e d b ( s q l i t e 3 ∗db ) {
s q l i t e 3 _ c l o s e ( db ) ;
}
int flush_db ( char∗ db_path , const double endtime ) {
s q l i t e 3 ∗db ;
const char c o n s t s q l [ ] = "BEGIN TRANSACTION; "
"DELETE FROM obd WHERE time < %−11.5 f ; "
"DELETE FROM gps WHERE time < %−11.5 f ; "
72
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"DELETE FROM t r i p WHERE end < %−11.5 f AND end > 0 ; "
"END TRANSACTION; " ;
char s q l [ 1 8 7 ] ;
char ∗ s q l e r r o r ;
i f ( ( db = opendb ( db_path ) ) == NULL) {
perror ( " Error opening database " ) ;
return 1 ;
}
s p r i n t f ( sql , c o n s t s q l , endtime , endtime , endtime ) ;
// p r i n t f ( "SQL: %s\n " , s q l ) ;
75
76
77
78
79
80
81
82 }
I.5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
i f ( s q l i t e 3 _ e x e c ( db , sql , NULL, NULL, &s q l e r r o r ) !=
SQLITE_OK) {
perror ( s q l e r r o r ) ;
sqlite3_free ( sqlerror ) ;
return 1 ;
}
c l o s e d b ( db ) ;
return 0 ;
networking.h
/∗
∗∗ NETWORKING.H
∗ Author : A l c i d e s Carlos de Moraes Neto
∗ This f i l e i s part o f o b d t e l e m e t r y c l i e n t
∗/
#ifndef _NETWORKING_H
#define _NETWORKING_H
#include
#include
#include
#include
#include
#include
#include
< s t d i o . h>
< s t d l i b . h>
<unistd . h>
<errno . h>
< s t r i n g . h>
<netdb . h>
<sys / types . h>
73
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include < n e t i n e t / in . h>
#include <sys / s o c k e t . h>
#include <arpa / i n e t . h>
#define PORT " 22490 "
#ifdef __cplusplus
extern "C" {
#endif
// g e t s o c k e t address
void ∗ get_in_addr ( struct sockaddr ∗ sa ) ;
// c onnect a new s o c k e t in s o c k f d t o hostname
int c o n ne c t s o c ke t ( char ∗hostname , int ∗ sockfd ) ;
// r e c e i v e data and check i f a l l b y t e s were r e c e i v e d
int recv_chk ( int sockfd , void ∗ b u f f e r , s s i z e _ t len , int
flags ) ;
35
36 // send data and check i f a l l b y t e s were s e n t
37 int send_chk ( int sockfd , const void ∗ data , s s i z e _ t len , int
flags ) ;
38
39 /∗ send FILE f through s o c k e t sock , in p i e c e s o f s i z e buflen
, by t h e s e s t e p s :
40 ∗ 1− Send f i l e s i z e as i n t
41 ∗ 2− Send b u f l e n b y t e s o f FILE f
42 ∗ 3− Recv ACK in the form o f i n t
43 ∗
− I f i t ’ s the number o f the p i e c e , send the next one
44 ∗
− I f i t ’ s d i f f e r e n t , i t means t h e r e was an e r r o r . Send
the l a s t p i e c e again .
45 ∗/
46 int s e n d _ f i l e ( FILE∗ f , int sock , s i z e _ t buflen ) ;
47
48 # i f d e f _ _ c p l u s p l u s
49 }
50 #endif
51
52 #endif /∗ _NETWORKING_H ∗/
74
I.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
networking.c
/∗
∗∗ NETWORKING.C
∗ Author : A l c i d e s Carlos de Moraes Neto
∗ This f i l e i s part o f o b d t e l e m e t r y c l i e n t
∗/
#include " networking . h"
void ∗ get_in_addr ( struct sockaddr ∗ sa )
{
i f ( sa−>sa_family == AF_INET) {
return & ( ( ( struct sockaddr_in ∗ ) sa )−>sin_addr ) ;
}
return & ( ( ( struct sockaddr_in6 ∗ ) sa )−>sin6_addr ) ;
}
int c o n ne c t s o c k et ( char ∗hostname , int ∗ sockfd ) {
struct addrinfo hints , ∗ s e r v i n f o , ∗p ;
int rv ;
char s [INET6_ADDRSTRLEN ] ;
memset(& hints , 0 , sizeof h i n t s ) ;
h i n t s . a i _ f a m i l y = AF_UNSPEC;
h i n t s . a i _ s o c k t y p e = SOCK_STREAM;
i f ( ( rv = g e t a d d r i n f o ( hostname , PORT, &hints , &s e r v i n f o )
) != 0 ) {
f p r i n t f ( stderr , " g e t a d d r i n f o : %s\n" , g a i _ s t r e r r o r ( rv
));
return −1;
}
// loop through a l l the r e s u l t s and connect t o the f i r s t
we can
for ( p = s e r v i n f o ; p != NULL; p = p−>ai_next ) {
i f ( ( ∗ sockfd = s o c k e t ( p−>ai_family , p−>ai_socktype ,
p−>a i _ p r o t o c o l ) ) == −1) {
perror ( " c l i e n t : s o c k e t " ) ;
continue ;
}
75
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
i f ( connect ( ∗ sockfd , p−>ai_addr , p−>ai_addrlen ) ==
−1) {
c l o s e ( ∗ sockfd ) ;
perror ( " c l i e n t : connect " ) ;
continue ;
}
break ;
}
i f ( p == NULL) {
f p r i n t f ( stderr , " c l i e n t : f a i l e d t o connect\n" ) ;
return −1;
}
i n e t _ n t o p ( p−>ai_family , get_in_addr ( ( struct sockaddr ∗ ) p
−>ai_addr ) ,
s , sizeof s ) ;
p r i n t f ( " c l i e n t : connecting t o %s\n" , s ) ;
56
57
58
59
f r e e a d d r i n f o ( s e r v i n f o ) ; // a l l done with t h i s s t r u c t u r e
60
return 0 ;
61 }
62
63
64 int recv_chk ( int sockfd , void ∗ b u f f e r , s s i z e _ t len , int
flags ) {
65
s s i z e _ t recvd =0;
66
recvd = recv ( sockfd , b u f f e r , len , f l a g s ) ;
67
i f ( recvd < len ) {
68
perror ( " recv returned l e s s than expected " ) ;
69
return −1;
70
}
71
return 0 ;
72 }
73
74 int send_chk ( int sockfd , const void ∗ b u f f e r , s s i z e _ t len ,
int f l a g s ) {
75
s s i z e _ t sent =0;
76
sent = send ( sockfd , b u f f e r , len , f l a g s ) ;
77
i f ( sent < len ) {
78
perror ( " send returned l e s s than expected " ) ;
79
return −1;
76
80
81
82 }
83
84 int
85 {
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
}
return 0 ;
s e n d _ f i l e ( FILE∗ f , int sock , s i z e _ t buflen )
char buf [ buflen ] ;
s s i z e _ t len ;
long int f i l e l e n ;
int ack =0 , i =0;
// f i n d i n g out f i l e s i z e
f s e e k ( f , 0 , SEEK_END) ;
p r i n t f ( " Sending f i l e s i z e : %d . \n" , f t e l l ( f ) ) ;
f i l e l e n = htonl ( f t e l l ( f ) ) ;
f s e e k ( f , 0 , SEEK_SET) ;
// f i r s t thing s e n t i s f i l e s i z e
i f ( send_chk ( sock , &f i l e l e n , sizeof ( long int ) , 0 ) < 0 ) {
perror ( " Error sending f i l e s i z e . " ) ;
return ( 1 ) ;
}
p r i n t f ( " F i l e s i z e sent . Sending f i l e . . . \ n" ) ;
while ( ( len = fread ( buf , sizeof ( char ) , buflen , f ) ) > 0 )
{
do {
i f ( send ( sock , buf , len , 0 ) < 0 ) {
perror ( " Error sending data . " ) ;
return ( 1 ) ;
}
// r e c e i v i n g ACK. I f ack == p i e c e number ( i ) ,
then proceed .
// I f i t ’ s not , send again .
recv_chk ( sock , &ack , sizeof ( int ) , 0 ) ;
} while ( ntohl ( ack ) != i ) ;
i ++;
}
if ( ferror ( f ) ) {
perror ( " Error reading f i l e . " ) ;
return ( 1 ) ;
}
return ( 0 ) ;
77
123 }
78
Anexo II
Código-fonte do servidor
II.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Main.java
/∗
∗ Main . java
∗ Author : A l c i d e s Carlos de Moraes Neto
∗ This f i l e i s part o f OBD Telemetry Server
∗/
package obdTelemetryServer ;
import
import
import
import
import
import
import
java . i o . F i l e ;
java . i o . FileReader ;
java . i o . IOException ;
java . net . ServerSocket ;
java . u t i l . P r o p e r t i e s ;
java . u t i l . l o g g i n g . Level ;
java . u t i l . l o g g i n g . Logger ;
/∗∗
∗
∗ @author A l c i d e s Carlos de Moraes Neto
∗/
public class Main {
/∗∗
∗ @param args the command l i n e arguments
∗/
public s t a t i c void main ( String [ ] args ) {
ServerSocket srvSock = null ;
// −− Configuration −− //
79
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// d e f a u l t s
int b u f f e r = 1024;
int port = 22490;
String logsPath = "C:\\ obdlogs\\ " ;
// f i l e
F i l e f = new F i l e ( " obdtelemetryserver . c f g " ) ;
i f ( f . canRead ( ) ) {
P r o p e r t i e s c o n f i g = new P r o p e r t i e s ( ) ;
try {
c o n f i g . load (new FileReader ( f ) ) ;
} catch ( IOException ex ) {
System . e r r . p r i n t l n ( " Error reading
c o n f i g u r a t i o n f i l e : " + ex .
getLocalizedMessage ( ) ) ;
System . e x i t ( 1 ) ;
}
String cfgValue = c o n f i g . getProperty ( " b u f f e r " ) ;
i f ( cfgValue != null ) {
try {
b u f f e r = I n t e g e r . parseInt ( cfgValue ) ;
} catch ( Exception e ) {
System . e r r . p r i n t l n ( " Error reading
configuration f i l e : Invalid ’ buffer ’
attribute . " ) ;
System . e x i t ( 1 ) ;
}
}
cfgValue = c o n f i g . getProperty ( " port " ) ;
i f ( cfgValue != null ) {
try {
port = I n t e g e r . parseInt ( cfgValue ) ;
} catch ( Exception e ) {
System . e r r . p r i n t l n ( " Error reading
c o n f i g u r a t i o n f i l e : I n v a l i d ’ port ’
attribute . " ) ;
System . e x i t ( 1 ) ;
}
}
cfgValue = c o n f i g . getProperty ( " logsPath " ) ;
i f ( cfgValue != null ) logsPath = cfgValue ;
}
try {
srvSock = new ServerSocket ( port ) ;
80
68
69
} catch ( IOException ex ) {
System . e r r . p r i n t l n ( " Error l i s t e n i n g on port
22490. " ) ;
System . e x i t ( 1 ) ;
}
70
71
72
73
74
75
76
System . out . p r i n t l n ( " Waiting f o r c o n n e c t i o n s . . . " ) ;
while ( ! srvSock . i s C l o s e d ( ) ) {
try {
new ServerThread ( srvSock . accept ( ) , b u f f e r ,
logsPath ) . s t a r t ( ) ;
} catch ( IOException ex ) {
System . e r r . p r i n t l n ( " Error a c c e p t i n g
connection : " + ex . getLocalizedMessage ( ) )
;
continue ;
}
}
77
78
79
80
81
82
83
84 }
II.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
}
ServerThread.java
/∗
∗ ServerThread . java
∗ Author : A l c i d e s Carlos de Moraes Neto
∗ This f i l e i s part o f OBD Telemetry Server
∗/
package obdTelemetryServer ;
import
import
import
import
import
import
import
import
import
import
au . com . bytecode . opencsv . CSVReader ;
java . i o . DataInputStream ;
java . i o . F i l e ;
java . i o . FileInputStream ;
java . i o . FileOutputStream ;
java . i o . FileReader ;
java . i o . IOException ;
java . i o . OutputStream ;
java . net . Socket ;
java . u t i l . ArrayList ;
81
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import
import
import
import
import
java . u t i l . Date ;
java . u t i l . z i p . GZIPInputStream ;
obdTelemetryServer . beans . Vehicle ;
obdTelemetryServer . db . ObdDao ;
obdTelemetryServer . db . VehicleDao ;
/∗∗
∗
∗ @author A l c i d e s Carlos de Moraes Neto
∗/
public class ServerThread extends Thread {
// CLIENT COMMANDS //
private s t a t i c final int
private s t a t i c final int
private s t a t i c final int
private s t a t i c final int
private s t a t i c final int
private s t a t i c final int
CMD_SEND_LICENSE = 1 ;
CMD_RECV_BUFFERSZ = 2 ;
CMD_SEND_NUMFILES = 3 ;
CMD_SEND_FILES = 4 ;
CMD_RECV_SLEEPTM = 5 ;
CMD_BYE = 9 9 ;
private final Socket sock ;
private final int b u f f e r ;
private final String logsPath ;
ServerThread ( Socket sock , int b u f f e r , String logsPath ) {
this . sock = sock ;
this . b u f f e r = b u f f e r ;
this . logsPath = logsPath ;
}
@Override
public void run ( ) {
i f ( this . sock == null ) {
throw new NullPointerException ( " Socket i s n u l l " )
;
}
Date now = new Date ( ) ;
OutputStream sockOut = null ;
DataInputStream sockDataIn = null ;
try {
System . out . p r i n t l n ( "New connection from " + this
. sock . getInetAddress ( ) . getHostAddress ( ) ) ;
82
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//sockOut = new BufferedOutputStream ( t h i s . sock .
getOutputStream ( ) ) ;
sockOut = this . sock . getOutputStream ( ) ;
sockDataIn = new DataInputStream ( this . sock .
getInputStream ( ) ) ;
//sockStrIn = new BufferedReader ( new
InputStreamReader ( t h i s . sock . getInputStream ( ) )
);
System . out . p r i n t ( " Receiving v e h i c l e l i c e n s e . . . " )
;
sockOut . write (CMD_SEND_LICENSE) ;
byte l i c e n s e B y t e s [ ] = new byte [ 8 ] ;
sockDataIn . read ( l i c e n s e B y t e s ) ;
String l i c e n s e = new String ( l i c e n s e B y t e s ) . trim ( )
;
System . out . p r i n t l n ( " done . Value : " + l i c e n s e ) ;
Vehicle v = new VehicleDao ( ) . g e t V e h i c l e ( l i c e n s e )
;
i f ( v == null ) {
System . out . p r i n t l n ( " Vehicle not r e g i s t e r e d ,
c l o s i n g connection . " ) ;
this . sock . c l o s e ( ) ;
return ;
}
System . out . p r i n t l n ( " Vehicle : " + v .
g e t D e s c r i p t i o n ( ) + " ( i d = " + v . getId ( ) + " ) " )
;
System . out . p r i n t ( " Sending b u f f e r s i z e . . . " ) ;
sockOut . write (CMD_RECV_BUFFERSZ) ;
sockOut . write ( intToByteArray ( b u f f e r ) ) ;
System . out . p r i n t l n ( " done . " ) ;
System . out . p r i n t ( " Receiving number o f f i l e s . . . " )
;
sockOut . write (CMD_SEND_NUMFILES) ;
int f i l e s Q t = sockDataIn . readInt ( ) ;
System . out . p r i n t l n ( " done . Value : " + f i l e s Q t ) ;
System . out . p r i n t l n ( " Receiving f i l e s . . . " ) ;
83
94
95
96
97
98
ArrayList <Fi le > f i l e s = new ArrayList <F il e > ( ) ;
sockOut . write (CMD_SEND_FILES) ;
for ( int i =0; i < f i l e s Q t ; i ++) {
//R e c e i v e gz ’ ed f i l e , uncompress and d e l e t e
it
99
F i l e gz = new F i l e ( logsPath + " obd_ " +
l i c e n s e + " _ " + now . getTime ( ) + " _ " + i +
" . csv . gz " ) ;
100
System . out . p r i n t l n ( "New gz f i l e : " + gz .
getCanonicalPath ( ) ) ;
101
r e c e i v e F i l e ( sockDataIn , sockOut , gz ) ;
102
F i l e f = uncompressFile ( gz ) ;
103 //
i f ( ! gz . d e l e t e ( ) ) {
104 //
throw new IOException ( " Could not
d e l e t e f i l e " + gz . getCanonicalPath ( ) ) ;
105 //
}
106
// Add f i l e s t o a l i s t t o be p r o c e s s e d a f t e r
sending bye message t o c l i e n t ,
107
// because i t can take a while .
108
f i l e s . add ( f ) ;
109
}
110
111
sockOut . write (CMD_BYE) ;
112
113
for ( F i l e f : f i l e s ) {
114
//Save CSV data do DB and d e l e t e the f i l e
115
storeData ( v , f ) ;
116
if ( ! f . delete ( ) ) {
117
throw new IOException ( " Could not d e l e t e
f i l e " + f . getCanonicalPath ( ) ) ;
118
}
119
}
120
121
} catch ( IOException ex ) {
122
System . e r r . p r i n t l n ( " Error during s o c k e t or f i l e
IO o p e r a t i o n : " + ex . getLocalizedMessage ( ) ) ;
123
ex . printStackTrace ( ) ;
124
return ;
125
} finally {
126
try {
127
i f ( sockOut != null ) sockOut . c l o s e ( ) ;
128
i f ( sockDataIn != null ) sockDataIn . c l o s e ( ) ;
129
this . sock . c l o s e ( ) ;
84
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
} catch ( Exception ex ) { }
}
}
private byte [ ] intToByteArray ( int value ) {
return new byte [ ] {
( byte ) ( value >>> 24) ,
( byte ) ( value >> 16 & 0 x f f ) ,
( byte ) ( value >> 8 & 0 x f f ) ,
( byte ) ( value & 0 x f f )
};
}
private void r e c e i v e F i l e ( DataInputStream sockIn ,
OutputStream sockOut , F i l e f ) throws IOException {
FileOutputStream fOut = null ;
try {
System . out . p r i n t ( " Receiving f i l e s i z e . . . " ) ;
int f i l e S i z e = sockIn . readInt ( ) ;
System . out . p r i n t l n ( " done . Value : " + f i l e S i z e ) ;
// Calculating f i l e p i e c e s
int p i e c e s ;
int l a s t P i e c e S i z e ;
pieces = f i l e S i z e / buffer ;
lastPieceSize = f i l e S i z e % buffer ;
fOut = new FileOutputStream ( f ) ;
Date s t a r t = new Date ( ) ;
for ( int i = 0 ; i < p i e c e s ; i ++) {
r e c e i v e F i l e P i e c e ( sockIn , sockOut , fOut , i ,
buffer ) ;
}
i f ( lastPieceSize > 0) {
r e c e i v e F i l e P i e c e ( sockIn , sockOut , fOut ,
pi ec es , l a s t P i e c e S i z e ) ;
}
long time = new Date ( ) . getTime ( ) − s t a r t . getTime
() ;
fOut . c l o s e ( ) ;
System . out . p r i n t l n ( " Finished f i l e . Time taken : "
+ time + "ms" ) ;
85
168
System . out . p r i n t l n ( " Transfer r a t e : " + ( ( ( f l o a t )
f i l e S i z e ) / time ) + " b / ms ( kb / s ) " ) ;
} catch ( IOException ex ) {
i f ( fOut != null ) {
fOut . c l o s e ( ) ;
f . delete ( ) ;
}
throw new IOException ( " F i l e or Socket stream IO
Error while r e c e i v i n g f i l e . " , ex ) ;
}
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
}
private void r e c e i v e F i l e P i e c e ( DataInputStream sockIn ,
OutputStream sockOut , FileOutputStream fOut , int
number , int length ) throws IOException {
byte [ ] inBuf = new byte [ length ] ;
int bytesRead = 0 ;
while ( ( bytesRead = sockIn . read ( inBuf ) ) < length ) {
i f ( bytesRead == −1) {
throw new IOException ( " Unexpected EOF in
s o c k e t input stream . " ) ;
}
sockOut . write ( intToByteArray ( −1) ) ;
}
fOut . write ( inBuf ) ;
sockOut . write ( intToByteArray ( number ) ) ;
}
private F i l e uncompressFile ( F i l e gz ) throws IOException
{
GZIPInputStream gzin = new GZIPInputStream (new
FileInputStream ( gz ) ) ;
// F i l e f = new F i l e ( gz . getCanonicalPath ( ) .
r e p l a c e F i r s t ( " . gz " , " " ) ) ;
//Remove . gz e x t e n s i o n
F i l e f = new F i l e ( gz . getCanonicalPath ( ) . s u b s t r i n g ( 0 ,
gz . getCanonicalPath ( ) . length ( ) −3) ) ;
FileOutputStream f o u t = new FileOutputStream ( f ) ;
int data = gzin . read ( ) ;
while ( data != −1) {
f o u t . write ( data ) ;
data = gzin . read ( ) ;
}
gzin . c l o s e ( ) ;
86
203
204
205
206
207
fout . close ( ) ;
return f ;
}
private void storeData ( Vehicle v , F i l e f ) throws
IOException {
CSVReader c s v r = new CSVReader (new FileReader ( f ) ) ;
ObdDao obddao = new ObdDao ( getCsvObdColumns ( c s v r .
readNext ( ) ) ) ;
String [ ] l i n e = c s v r . readNext ( ) ;
while ( l i n e != null ) {
i f ( ! obddao . storeCsvLine ( v . getId ( ) , l i n e ) ) {
System . e r r . p r i n t l n ( " Error s t o r i n g csv l i n e . "
);
}
l i n e = c s v r . readNext ( ) ;
}
csvr . close ( ) ;
}
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 }
II.3
// Get obd column names from csv , without the " obd . "
prefix .
private String [ ] getCsvObdColumns ( String [ ] csvcolumns ) {
int len =0;
//Counting " obd . " columns
while ( len < csvcolumns . length && csvcolumns [ len ] .
startsWith ( " obd . " ) ) len ++;
String [ ] toReturn = new String [ len ] ;
for ( int i = 0 ; i < toReturn . length ; i ++) {
toReturn [ i ] = csvcolumns [ i ] . r e p l a c e F i r s t ( " obd . " ,
"") ;
}
return toReturn ;
}
DbConnector.java
1 /∗
2 ∗ DbConnector . java
3 ∗ Author : A l c i d e s Carlos de Moraes Neto
87
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
∗ This f i l e i s part o f OBD Telemetry Server
∗/
package obdTelemetryServer . db ;
import
import
import
import
import
java . s q l . Connection ;
java . s q l . DriverManager ;
java . s q l . PreparedStatement ;
java . s q l . SQLException ;
java . s q l . Statement ;
/∗∗
∗
∗ @author A l c i d e s Carlos de Moraes Neto
∗/
public class DbConnector {
private s t a t i c final String
Driver " ;
private s t a t i c final String
l o c a l h o s t / karmonitor " ;
private s t a t i c final String
private s t a t i c final String
DB_DRV = " org . p o s t g r e s q l .
DB_URL = " j d b c : p o s t g r e s q l : / /
DB_USR = " karmonitor " ;
DB_PWD = " karmonitor " ;
private Connection conn ;
public DbConnector ( ) throws SQLException {
this (DB_DRV, DB_URL, DB_USR, DB_PWD) ;
}
public DbConnector ( String driver , String url , String
user , String passwd ) throws SQLException {
try {
Class . forName ( d r i v e r ) ;
conn = DriverManager . getConnection ( url , user ,
passwd ) ;
conn . setAutoCommit ( false ) ;
} catch ( ClassNotFoundException ex ) {
throw new RuntimeException ( " Could not load DB
d r i v e r " + driver , ex ) ;
}
}
@Override
protected void f i n a l i z e ( ) throws Throwable {
88
43
44
45
46
47
48
49
50
51
52
53
54
55
conn . r o l l b a c k ( ) ;
conn . c l o s e ( ) ;
}
public void commit ( ) throws SQLException {
conn . commit ( ) ;
}
public Statement createStatement ( ) throws SQLException {
return conn . createStatement ( ) ;
}
public PreparedStatement prepareStatement ( String s q l )
throws SQLException {
return conn . prepareStatement ( s q l ) ;
}
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 }
II.4
/∗∗
∗ Execute prepared statement t h a t i s an update .
∗ @param s t Prepared statement with a l l f i e l d s s e t
∗ @return t r u e i f the statement e x e c u t i o n r e t u r n s an
update
∗ @throws SQLException
∗/
public boolean executePreparedStatementUpdate (
PreparedStatement s t ) throws SQLException {
i f ( s t == null ) {
throw new NullPointerException ( "
PreparedStatement s t i s n u l l . " ) ;
}
boolean r e s u l t = ! s t . execute ( ) ;
st . close ( ) ;
return r e s u l t ;
}
ObdDao.java
1 /∗
2 ∗ ObdDao . java
3 ∗ Author : A l c i d e s Carlos de Moraes Neto
89
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
∗ This f i l e i s part o f OBD Telemetry Server
∗/
package obdTelemetryServer . db ;
import java . math . BigDecimal ;
import java . s q l . PreparedStatement ;
/∗∗
∗
∗ @author A l c i d e s Carlos de Moraes Neto
∗/
public class ObdDao {
private String i n s e r t S q l ;
private int numObdColumns ;
public ObdDao ( String [ ] obdColumns ) {
i n s e r t S q l = "INSERT INTO \"OBDGPSDATA\" ( \ "
id_vehicle \" , " ;
//obd columns from csv i n t o s q l
for ( int i = 0 ; i < obdColumns . length ; i ++) {
i n s e r t S q l += " \" " + obdColumns [ i ] + " \ " , " ;
}
i n s e r t S q l += " \" gps_lon \ " , \ " g p s _ l a t \ " , \ " g p s _ a l t \ " )
VALUES ( ? , " ;
for ( int i = 0 ; i < obdColumns . length ; i ++) {
i n s e r t S q l += " ? , " ;
}
i n s e r t S q l += " ? , ? , ? ) " ;
numObdColumns = obdColumns . length ;
System . out . p r i n t l n ( "ObdDao . i n s e r t S q l : " + i n s e r t S q l )
;
}
public boolean storeCsvLine ( int v e h i c l e I d , String [ ] l i n e
) {
DbConnector db=null ;
PreparedStatement s t =null ;
try {
db = new DbConnector ( ) ;
s t = db . prepareStatement ( i n s e r t S q l ) ;
st . setInt (1 , vehicleId ) ;
// Obd columns are f i r s t in CSV
90
44
45
for ( int i = 0 ; i < numObdColumns ; i ++) {
// s t . s e t F l o a t ( i +2 , Float . parseFloat ( l i n e [ i ] )
);
BigDecimal bd = new BigDecimal ( l i n e [ i ] ) ;
s t . setBigDecimal ( i +2 , bd ) ;
}
//gps and t r i p are the l a s t ones
s t . s e t F l o a t ( numObdColumns+2 , Float . parseFloat (
l i n e [ l i n e . length −4]) ) ; //gps . lon
s t . s e t F l o a t ( numObdColumns+3 , Float . parseFloat (
l i n e [ l i n e . length −3]) ) ; //gps . l a t
s t . s e t F l o a t ( numObdColumns+4 , Float . parseFloat (
l i n e [ l i n e . length −2]) ) ; //gps . a l t
46
47
48
49
50
51
52
53
54
boolean r e s u l t = db .
executePreparedStatementUpdate ( s t ) ;
i f ( r e s u l t ) db . commit ( ) ;
return r e s u l t ;
} catch ( Exception ex ) {
System . e r r . p r i n t l n ( " Error s t o r i n g csv l i n e : " +
ex . getLocalizedMessage ( ) ) ;
ex . printStackTrace ( ) ;
return false ;
}
55
56
57
58
59
60
61
62
63
64 }
II.5
}
Vehicle.java
1 /∗
2 ∗ V e h i c l e . java
3 ∗ Author : A l c i d e s Carlos de Moraes Neto
4 ∗ This f i l e i s part o f OBD Telemetry Server
5 ∗/
6
7 package obdTelemetryServer . beans ;
8
9 /∗∗
10 ∗
11 ∗ @author A l c i d e s Carlos de Moraes Neto
12 ∗/
91
13 public class Vehicle {
14
15
private int i d ;
16
private String l i c e n s e ;
17
private String d e s c r i p t i o n ;
18
19
/∗∗
20
∗ @return the id
21
∗/
22
public int getId ( ) {
23
return i d ;
24
}
25
26
/∗∗
27
∗ @param id the id t o s e t
28
∗/
29
public void s e t I d ( int i d ) {
30
this . i d = i d ;
31
}
32
33
/∗∗
34
∗ @return the l i c e n s e
35
∗/
36
public String getLicense ( ) {
37
return l i c e n s e ;
38
}
39
40
/∗∗
41
∗ @param l i c e n s e the l i c e n s e t o s e t
42
∗/
43
public void s e t L i c e n s e ( String l i c e n s e ) {
44
this . l i c e n s e = l i c e n s e ;
45
}
46
47
/∗∗
48
∗ @return the d e s c r i p t i o n
49
∗/
50
public String g e t D e s c r i p t i o n ( ) {
51
return d e s c r i p t i o n ;
52
}
53
54
/∗∗
55
∗ @param d e s c r i p t i o n the d e s c r i p t i o n t o s e t
56
∗/
92
57
58
59
60
61 }
II.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void s e t D e s c r i p t i o n ( String d e s c r i p t i o n ) {
this . d e s c r i p t i o n = d e s c r i p t i o n ;
}
VehicleDao.java
/∗
∗ VehicleDao . java
∗ Author : A l c i d e s Carlos de Moraes Neto
∗ This f i l e i s part o f OBD Telemetry Server
∗/
package obdTelemetryServer . db ;
import
import
import
import
java . s q l . PreparedStatement ;
java . s q l . ResultSet ;
java . s q l . SQLException ;
obdTelemetryServer . beans . Vehicle ;
/∗∗
∗
∗ @author A l c i d e s Carlos de Moraes Neto
∗/
public class VehicleDao {
public Vehicle g e t V e h i c l e ( String l i c e n s e ) {
try {
String s q l = "SELECT id , d e s c r i p t i o n FROM \"
VEHICLE\" " +
" WHERE l i c e n s e = ? " ;
DbConnector db = new DbConnector ( ) ;
PreparedStatement s t = db . prepareStatement ( s q l ) ;
st . setString (1 , license ) ;
ResultSet rs = s t . executeQuery ( ) ;
Vehicle v = null ;
i f ( rs . next ( ) ) {
v = new Vehicle ( ) ;
v . s e t I d ( rs . g e t I n t ( " i d " ) ) ;
v . setLicense ( license ) ;
93
33
v . s e t D e s c r i p t i o n ( rs . g e t S t r i n g ( " d e s c r i p t i o n " )
);
34
35
36
37
38
39
40
41
42
43
44 }
}
rs . c l o s e ( ) ;
st . close ( ) ;
return v ;
} catch ( SQLException ex ) {
System . out . p r i n t l n ( "SQL EXCEPTION: " + ex .
getLocalizedMessage ( ) ) ;
throw new RuntimeException ( ex ) ;
}
}
94
Anexo III
Tabelas do banco de dados do
servidor
Tabelas criadas no banco PostgreSQL, para armazenamento de dados OBD pelo
servidor.
III.1
1
2
3
4
5
6
7
8
9
10
11
12
Tabela VEHICLE
CREATE TABLE "VEHICLE"
(
i d s e r i a l NOT NULL,
l i c e n s e character ( 7 ) NOT NULL,
d e s c r i p t i o n text ,
CONSTRAINT "VEHICLE_pkey" PRIMARY KEY ( i d ) ,
CONSTRAINT " VEHICLE_license_key " UNIQUE ( l i c e n s e )
)
WITH (
OIDS=FALSE
);
III.2
Tabela OBDGPSDATA
1
2
3 CREATE TABLE "OBDGPSDATA"
4 (
5
i d _ v e h i c l e integer NOT NULL,
6
g p s _ l a t numeric NOT NULL,
95
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
gps_lon numeric NOT NULL,
g p s _ a l t numeric NOT NULL,
d t c f r z f integer , −− DTC t h a t caused r e q u i r e d f r e e z e frame
data s t o r a g e
f u e l s y s integer , −− Fuel system 1 and 2 s t a t u s
l o a d _ p c t numeric ( 9 , 6 ) , −− Calculated LOAD Value
" temp " integer , −− Engine Coolant Temperature
s h r t f t 1 3 numeric ( 9 , 6 ) , −− Short Term Fuel Trim − Bank 1 ,3
l o n g f t 1 3 numeric ( 9 , 6 ) , −− Long Term Fuel Trim − Bank 1 ,3
s h r t f t 2 4 numeric ( 9 , 6 ) , −− Short Term Fuel Trim − Bank 2 ,4
l o n g f t 2 4 numeric ( 9 , 6 ) , −− Long Term Fuel Trim − Bank 2 ,4
f r p integer , −− Fuel Rail Pressure ( gauge )
map integer , −− Intake Manifold Absolute Pressure
rpm numeric ( 7 , 2 ) , −− Engine RPM
vss integer , −− V e h i c l e Speed Sensor
sparkadv numeric ( 3 , 1 ) , −− I g n i t i o n Timing Advance f o r #1
Cylinder
i a t integer , −− Intake Air Temperature
maf numeric ( 9 , 6 ) , −− Air Flow Rate from Mass Air Flow
Sensor
t h r o t t l e p o s numeric ( 9 , 6 ) , −− Absolute T h r o t t l e P o s i t i o n
a i r _ s t a t integer , −− Commanded Secondary Air Status
o 2 s l o c integer , −− Location o f Oxygen Sensors
o2s11 numeric ( 6 , 3 ) , −− Bank 1 − Sensor 1/Bank 1 − Sensor 1
Oxygen Sensor Output Voltage / Short Term Fuel Trim
o2s12 numeric ( 6 , 3 ) , −− Bank 1 − Sensor 2/Bank 1 − Sensor 2
Oxygen Sensor Output Voltage / Short Term Fuel Trim
o2s13 numeric ( 6 , 3 ) , −− Bank 1 − Sensor 3/Bank 2 − Sensor 1
Oxygen Sensor Output Voltage / Short Term Fuel Trim
o2s14 numeric ( 6 , 3 ) , −− Bank 1 − Sensor 4/Bank 2 − Sensor 2
Oxygen Sensor Output Voltage / Short Term Fuel Trim
o2s21 numeric ( 6 , 3 ) , −− Bank 2 − Sensor 1/Bank 3 − Sensor 1
Oxygen Sensor Output Voltage / Short Term Fuel Trim
o2s22 numeric ( 6 , 3 ) , −− Bank 2 − Sensor 2/Bank 3 − Sensor 2
Oxygen Sensor Output Voltage / Short Term Fuel Trim
o2s23 numeric ( 6 , 3 ) , −− Bank 2 − Sensor 3/Bank 4 − Sensor 1
Oxygen Sensor Output Voltage / Short Term Fuel Trim
o2s24 numeric ( 6 , 3 ) , −− Bank 2 − Sensor 4/Bank 4 − Sensor 2
Oxygen Sensor Output Voltage / Short Term Fuel Trim
obdsup integer , −− OBD requirements t o which v e h i c l e i s
designed
o 2 s l o c 2 integer , −− Location o f oxygen s e n s o r s
p t o _ s t a t integer , −− A u x i l i a r y Input Status
runtm integer , −− Time Since Engine S t a r t
96
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
m i l _ d i s t integer , −− Distance T r a v e l l e d While MIL i s
Activated
f r p r numeric ( 7 , 3 ) , −− Fuel Rail Pressure r e l a t i v e t o
manifold vacuum
frpd integer , −− Fuel Rail Pressure ( d i e s e l )
lambda11 numeric ( 8 , 7 ) , −− Bank 1 − Sensor 1/Bank 1 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
lambda12 numeric ( 8 , 7 ) , −− Bank 1 − Sensor 2/Bank 1 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
lambda13 numeric ( 8 , 7 ) , −− Bank 1 − Sensor 3 /Bank 2 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
lambda14 numeric ( 8 , 7 ) , −− Bank 1 − Sensor 4 /Bank 2 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
lambda21 numeric ( 8 , 7 ) , −− Bank 2 − Sensor 1 /Bank 3 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
lambda22 numeric ( 8 , 7 ) , −− Bank 2 − Sensor 2 /Bank 3 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
lambda23 numeric ( 8 , 7 ) , −− Bank 2 − Sensor 3 /Bank 4 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
lambda24 numeric ( 8 , 7 ) , −− Bank 2 − Sensor 4 /Bank 4 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Voltage
e g r _ p c t numeric ( 9 , 6 ) , −− Commanded EGR
e g r _ e r r numeric ( 9 , 6 ) , −− EGR Error
evap_pct numeric ( 9 , 6 ) , −− Commanded Evaporative Purge
f l i numeric ( 9 , 6 ) , −− Fuel Level Input
warm_ups smallint , −− Number o f warm−ups s i n c e d i a g n o s t i c
t r o u b l e codes c l e a r e d
c l r _ d i s t integer , −− Distance s i n c e d i a g n o s t i c t r o u b l e
codes c l e a r e d
evap_vp numeric ( 6 , 2 ) , −− Evap System Vapour Pressure
baro smallint , −− Barometric Pressure
lambdac11 numeric ( 1 1 , 8 ) , −− Bank 1 − Sensor 1/Bank 1 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
97
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
lambdac12 numeric ( 1 1 , 8 ) , −− Bank 1 − Sensor 2/Bank 1 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
lambdac13 numeric ( 1 1 , 8 ) , −− Bank 1 − Sensor 3/Bank 2 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
lambdac14 numeric ( 1 1 , 8 ) , −− Bank 1 − Sensor 4/Bank 2 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
lambdac21 numeric ( 1 1 , 8 ) , −− Bank 2 − Sensor 1/Bank 3 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
lambdac22 numeric ( 1 1 , 8 ) , −− Bank 2 − Sensor 2/Bank 3 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
lambdac23 numeric ( 1 1 , 8 ) , −− Bank 2 − Sensor 3/Bank 4 −
Sensor 1 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
lambdac24 numeric ( 1 1 , 8 ) , −− Bank 2 − Sensor 4/Bank 4 −
Sensor 2 ( wide range O2S) Oxygen Sensors Equivalence
Ratio ( lambda ) / Current
catemp11 numeric ( 5 , 1 ) , −− C a t a l y s t Temperature Bank 1 /
Sensor 1
catemp21 numeric ( 5 , 1 ) , −− C a t a l y s t Temperature Bank 2 /
Sensor 1
catemp12 numeric ( 5 , 1 ) , −− C a t a l y s t Temperature Bank 1 /
Sensor 2
catemp22 numeric ( 5 , 1 ) , −− C a t a l y s t Temperature Bank 2 /
Sensor 2
vpwr numeric ( 8 , 3 ) , −− Control module v o l t a g e
load_abs numeric ( 9 , 6 ) , −− Absolute Load Value
lambda numeric ( 8 , 7 ) , −− Fuel/ a i r Commanded Equivalence
Ratio
tp_r numeric ( 9 , 6 ) , −− R e l a t i v e T h r o t t l e P o s i t i o n
aat smallint , −− Ambient a i r temperature
tp_b numeric ( 9 , 6 ) , −− Absolute T h r o t t l e P o s i t i o n B
tp_c numeric ( 9 , 6 ) , −− Absolute T h r o t t l e P o s i t i o n C
app_d numeric ( 9 , 6 ) , −− A c c e l e r a t o r Pedal P o s i t i o n D
app_e numeric ( 9 , 6 ) , −− A c c e l e r a t o r Pedal P o s i t i o n E
app_f numeric ( 9 , 6 ) , −− A c c e l e r a t o r Pedal P o s i t i o n F
t a c _ p c t numeric ( 9 , 6 ) , −− Commanded T h r o t t l e Actuator
Control
mil_time integer , −− Time run by the engine while MIL
activated
98
82
83
84
85
86
87
c l r _ t i m e integer , −− Time s i n c e d i a g n o s t i c t r o u b l e codes
cleared
f u e l _ t y p e smallint , −− Fuel Type
a l c h _ p c t numeric ( 9 , 6 ) , −− Ethanol f u e l %
" time " numeric NOT NULL,
CONSTRAINT "OBDGPSDATA_pkey" PRIMARY KEY ( i d _ v e h i c l e , "
time " ) ,
CONSTRAINT " OBDGPSDATA_id_vehicle_fkey " FOREIGN KEY (
id_vehicle )
REFERENCES "VEHICLE" ( i d ) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
88
89
90 )
91 WITH (
92
OIDS=FALSE
93 ) ;
99