Vous êtes sur la page 1sur 104

Daniel Diegues

Rede CAN para Estimativa de Orientação e


Posição de Máquinas Agrícolas

São Carlos
2014
Daniel Diegues

Rede CAN para Estimativa de Orientação e Posição de


Máquinas Agrícolas

Trabalho de Conclusão de Curso apresentado


ao Departamento de Engenharia Elétrica da
Universidade Federal de São Carlos, como
parte dos requisitos para obtenção do grau
em Engenharia Elétrica.

Universidade Federal de São Carlos – UFSCar


Departamento de Engenharia Elétrica
Graduação em Engenharia Elétrica

Orientador: Prof. Dr. Roberto Santos Inoue

São Carlos
2014
Agradecimentos

Primeiramente a Deus e Maria que foram a forte rocha que me apoio em todos os
momentos da minha vida e durante toda a graduação.
De modo especial aos meus pais e irmão que sempre me ajudaram em todos os
momentos de minha vida. À minha noiva pela paciência, companheirismo e atenção, em
especial nos momentos em que o trabalho me afadigou.
Ao Professor Doutor Roberto Santos Inoue pelo tempo dedicado, por acreditar no
meu trabalho e dar as condições para a sua realização.
Ao Professor Doutor Arlindo Neto Montagnoli que me auxiliou muito no início da
minha graduação e é parte fundamental da minha formação e inserção no mundo científico.
Aos membros da banca pela contribuição e tempo dedicados a esse trabalho.
Aos professores e técnicos do Departamento de Engenharia Elétrica por todo o
apoio e aprendizado concedidos.
Aos amigos da turma pelos bons momentos vividos juntos, em especial Paulo
Roberto e Rafael Minutti que acompanharam mais de perto o desenvolvimento deste
trabalho.
“Portanto, não se preocupe com o dia de amanhã,
pois o dia de amanhã terá suas preocupações.
Basta a cada dia a própria dificuldade.”
(Bíblia Sagrada, Mateus 6, 34)
Resumo
Com o crescimento da agricultura de precisão, o emprego de sistemas de navegação com GPS
(Global Positioning System) em veículos agrícolas tem se tornado cada vez mais necessário,
com níveis elevados de exigências ligados à confiabilidade e exatidão.Acompanhando esse
crescimento, vem o uso intensivo da eletrônica embarcada nas máquinas agrícolas. Com
isso, surgem dois quadros, a necessidade de localização de sistemas móveis com elevada
precisão e a integração dessa eletrônica embarcada de forma eficaz. Para o problema
de localização, tem-se utilizado a fusão de sinais de uma IMU (Inertial Measurement
Unit) e de um receptor GPS para a estimativa de posição e orientação do veículo. E para
a integração da eletrônica embarcada tem-se utilizado redes de campo, sendo o CAN
(Controller Area Network) o protocolo de baixo nível mais proeminente nessa área. Dessa
forma, nesse trabalho de conclusão de curso é desenvolvido um protótipo de uma rede CAN
conectando três ECUs (Eletronic Central Unit). Duas ECUs realizam a aquisição dos dados
dos sensores e enviam para a ECU central que realiza o processamento e disponibiliza os
dados para o computador. Com o desenvolvimento dessa rede foi possível avaliar os atrasos
causados na recepção dos dados pela ECU central, bem como levantar as vantagens e
desvantagens de uma arquitetura modular descentralizada.

Palavras-chaves: Rede CAN, GPS, IMU, microcontrolador.


Abstract
With the growth of precision agriculture, the use of navigation systems with GPS (Global
Positioning System) in agricultural vehicles has become increasingly necessary, with
high levels of requirements associated with reliability and accuracy. With this growth
comes intensive use of embedded electronics in agricultural machines. Thus, there are two
situations, the need for location of mobile systems with high precision and integration of
electronic circuitry of an efficient way. For the localization problem, has been used the
fusion of a IMU (Inertial Measurement Unit) signal and a GPS receiver to estimate the
position and orientation of the vehicle. And for the integration of embedded electronics has
been used fieldbuses, and the CAN (Controller Area Network) the most prominent low-level
protocol in this area. Thus, in this work is developed a prototype of a CAN network
connecting three ECU (Electronic Central Unit). Two ECU perform data acquisition from
the sensors and send to the central ECU that performs processing and provides the data to
the computer. With the development of this network it can evaluate the delays in receiving
data by the central ECU and indicate the advantages and disadvantages of a decentralized
modular architecture.

Key-words: CAN bus, GPS, IMU, microcontroller.


Lista de ilustrações

Figura 1 – Cabine com instrumentos sem padrão (NISSEN, 2008 apud SUZUKI,
2012) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Figura 2 – Representação de uma arquitetura centralizada . . . . . . . . . . . . . 24
Figura 3 – Representação de uma arquitetura distribuída . . . . . . . . . . . . . . 24
Figura 4 – Camadas da rede CAN. Adaptado de: Bosch Gmbh (1991). . . . . . . . 27
Figura 5 – Níveis dos Sinais Elétricos ISO 11898-2. Retirado de: Di Natale et al.
(2012) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Figura 6 – Tempo de bit nominal. Adaptado de: Di Natale et al. (2012) . . . . . . 31
Figura 7 – Quadro de dados Fonte: Sousa (2002). . . . . . . . . . . . . . . . . . . 33
Figura 8 – Quadro remoto CAN 2.0b. Retirado de: Sousa (2002). . . . . . . . . . . 34
Figura 9 – Estados de erros possíveis. Retirado de: Sousa (2002). . . . . . . . . . . 35
Figura 10 – Exemplo do processo de arbitragem. Retirado de: Di Natale et al. (2012). 36
Figura 11 – Ilustração do conceito de multicast. Retirado de: CiA (2002). . . . . . . 37
Figura 12 – Máscara e filtro para mensagem CAN. Adaptado de: Di Natale et al.
(2012). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Figura 13 – Topologia do protótipo da rede de testes. . . . . . . . . . . . . . . . . . 42
Figura 14 – Topologias de ECU. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Figura 15 – Esquemático do circuito utilizado para as ECUs. . . . . . . . . . . . . 45
Figura 16 – Placa do circuito utilizado para as ECUs. . . . . . . . . . . . . . . . . 46
Figura 17 – Circuito do conversor de nível bidirecional. Retirado de: NXP Semicon-
ductors (2007). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Figura 18 – Placa receptor de GPS. Retirado de: SparkFun Electronics Inc. (2002). 48
Figura 19 – Esquemático da união na memória. . . . . . . . . . . . . . . . . . . . . 51
Figura 20 – Placa da IMU. Retirado de: SparkFun Electronics Inc. (2002). . . . . . 51
Figura 21 – Fluxograma da função principal da IMU. . . . . . . . . . . . . . . . . . 52
Figura 22 – Sinais CAN L e CAN H obtidos da rede implementada. . . . . . . . . . 55
Figura 23 – Medida de atraso da rede de testes. . . . . . . . . . . . . . . . . . . . . 56
Lista de tabelas

Tabela 1 – Características físicas da norma SAE J1939. Adaptado de: Di Natale et


al. (2012). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Tabela 2 – Regras práticas da norma ISO 11898 para comprimento do barramento
em função da taxa de transmissão. Adaptado de: Ferreira e Fonseca
(2011). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Tabela 3 – Dicionário de dados da rede. . . . . . . . . . . . . . . . . . . . . . . . . 42
Tabela 4 – Descrição dos campos da mensagem NMEA 0183 GPGGA. Modificado
de: SKYTRAQ Technology Inc. (2008). . . . . . . . . . . . . . . . . . . 49
Tabela 5 – Descrição dos campos da mensagem NMEA 0183 GPVTG. Modificado
de: SKYTRAQ Technology Inc. (2008). . . . . . . . . . . . . . . . . . . 49
Lista de abreviaturas e siglas

CAN Controller Area Network

GPS Global Position System

IMU Inertial Measurement Unit

INS Inertial Navegation System

ECU Electronic Control Unit

ISO International Starndards Organization

OSI Open Systems Interconnection

SAE Society of Automotive Engineers

TTCAN Time-Triggered CAN

FTT-CAN Flexible Time-Triggered CAN

NRZ Non Return to Zero

CSMA/NDBA Carrier Sense Multiple Acess/Collision Detection

SRR Substitute Remote Request

SOF Start of Frame

RTR Remote Transmission Request

DLC Data Length Code

CRC Cyclic Redundance Check

ACK Acknowledge

EOF End of Frame

IMO Inconsistent Message Omissions

IMD Inconsistent Message Duplicates

BER Bit Error Rate

UTC Universal Time Coordinated


USART Universal Synchronous Asynchronous Receiver Transmitter

TTL Transistor-Transistor Logic

LVTTL Low Voltage Transistor-Transistor Logic

USB Universial Serial Bus

NMEA National Marine Electronics Association


Sumário

1 INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2 ARQUITETURA DA ELETRÔNICA EMBARCADA E CONCEITOS


DE REDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1 Arquitetura centralizada . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2 Arquitetura distribuída . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3 Sistemas embarcado na agricultura de precisão . . . . . . . . . . . . 25
2.4 Conceitos básicos em redes de comunicação . . . . . . . . . . . . . . 26

3 A REDE CAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.1 Camada física . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.1.1 Codificação dos bits e níveis de sinal . . . . . . . . . . . . . . . . . . . . . 30
3.1.2 Temporização dos bits e sincronização . . . . . . . . . . . . . . . . . . . . 31
3.2 Camada de enlace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.2.1 Tipo de quadros da mensagem CAN . . . . . . . . . . . . . . . . . . . . . 33
3.2.2 Detecção, controle e sinalização de erros . . . . . . . . . . . . . . . . . . . 35
3.2.3 Mecanismo de acesso ao meio . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2.4 Filtro e aceitação de mensagens . . . . . . . . . . . . . . . . . . . . . . . 37
3.3 Limitações da CAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.4 A CAN na agricultura . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

4 IMPLEMENTAÇÃO DA REDE DE TESTES . . . . . . . . . . . . . 41


4.1 Topologia geral da rede . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.2 Arquitetura genérica das ECUs . . . . . . . . . . . . . . . . . . . . . . 43
4.2.1 Módulo ECAN do PIC18F2580 . . . . . . . . . . . . . . . . . . . . . . . . 44
4.2.2 Transceptor MCP2551 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.2.3 Conversor bidirecional . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.3 ECU do GPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.4 ECU da IMU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.5 ECU computador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

5 AVALIAÇÃO DA REDE E RESULTADOS . . . . . . . . . . . . . . . 55


5.1 Sinais elétricos da rede CAN . . . . . . . . . . . . . . . . . . . . . . . 55
5.2 Monitoramento de erros . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3 Atraso nos dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

6 CONSIDERAÇÕES FINAIS . . . . . . . . . . . . . . . . . . . . . . . 57
6.1 Trabalhos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.2 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Referências . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

APÊNDICES 61

APÊNDICE A – CÓDIGO MAIN ECU DO PC . . . . . . . . . . . 63

APÊNDICE B – CÓDIGO MAIN ECU DA IMU . . . . . . . . . . . 69

APÊNDICE C – CÓDIGO MAIN ECU DA GPS . . . . . . . . . . . 75

APÊNDICE D – CÓDIGOS BIBLIOTECA DA IMU . . . . . . . . . 79

APÊNDICE E – CÓDIGOS BIBLIOTECA DO GPS . . . . . . . . . 87

APÊNDICE F – CÓDIGOS BIBLIOTECA ECAN . . . . . . . . . . 97


19

1 Introdução

1.1 Motivação
A agricultura de precisão tem como objeto de estudo a lavoura com suas variabi-
lidades e fazendo uso de técnicas e métodos procura obter ganhos econômicos e menor
impacto ambiental. Hoje, especialmente no Brasil o foco tem sido principalmente nas
aplicações a taxas variáveis de fertilizantes e corretivos, mas sem perder o foco na gestão
(PEREIRA, 2008; INAMASU, 2013; MOLIN, 2013). Este conceito vem sendo utilizado
como uma das respostas aos desafios enfrentados pelos produtores agrícolas brasileiros,
que em uma economia cada vez mais globalizada, um ambiente de acirrada competição e
um aumento contínuo da demanda por alimentos, se torna vital a aplicação de processos
mais eficientes, com custos financeiros e ambientais cada vem menores. Além disso, os
mercados consumidores tornam-se mais exigentes nas questões de rastreabilidade, segu-
rança alimentar, sustentabilidade e energia renovável. É interessante notar que o Brasil
sai na frente no que diz respeito à capacidade de responder ao crescimento na demanda,
pois são poucos os países no mundo que possuem recursos naturais tão intensos quanto os
brasileiros (JUNTOLLI, 2013).
Porém a agricultura de precisão só pôde ser viável na prática com a aplicação da
eletrônica embarcada nas máquinas agrícolas, como tratores, colhedoras e implementos.
No entanto com o passar do tempo, essa utilização massiva da tecnologia embarcada se
tornou um amontoado de fios, telas e dispositivos eletrônicos na cabine do trator, tornando
a operação complicada e dificultando a difusão desses sistemas (INAMASU, 2013).

Figura 1 – Cabine com instrumentos sem padrão (NISSEN, 2008 apud SUZUKI, 2012)

A falta de padrão entre os fabricantes e uma arquitetura convencional da eletrônica


20 Capítulo 1. Introdução

embarcada, onde cada dispositivo, sensor ou atuador, possui sua própria interface com o
usuário e meio de comunicação, se tornam fatores determinantes desse fenômeno ilustrado
na Figura 1, onde pode ser vista uma cabine com a eletrônica embarcada sem padronização
(PEREIRA, 2008).
Diante desse panorama torna-se desejável encontrar novas formas de conceber esses
sistemas. Hoje vem sendo observada um tendencia de utilizar uma arquitetura distribuída
em conjunto com uma instrumentação inteligente. Esse conceito traz vantagens, como
o aumento da confiabilidade, com a detecção e correção automática de falhas, além de
autocalibração, preprocessamento e controle distribuído (STRAUSS, 2001).
O protocolo de comunicação digital mais destacado para essa aplicação é o CAN
(Controller Area Network), que é implementado nos automóveis desde a década de 80,
quando passavam pelos mesmos problemas citados na área agrícola. Além disso, o CAN se
tornou uma opção lógica por atender aos requisitos de robustez, exigidos pelo ambiente de
aplicação, velocidade, compactação e simplificação por ser um protocolo a dois fios e a sua
rastreabilidade possuir mecanismos de identificação unívocos dos dispositivos conectados.
Como evidências fortes dessa escolha, pode-se observar o surgimento de normas como, a
DIN 9684, a SAE J1939 e mais recentemente, com um apelo de padrão aberto buscando
aumentar a interoperabilidade dos sistemas, a ISO 11783, ainda segundo Sousa (2002),
mesmo o CAN já sendo utilizado por muitos fabricantes e se mostrar uma tecnologia
bastante promissora, existe uma necessidade de estudar as topologias, as prioridades de
cada sensor e atuador, além dos circuitos integrados e controladores que mais se adaptem
à aplicação em agricultura de precisão.
Molin (2013) enfatiza que, o surgimento do sistema norte americano de posicio-
namento global o GPS (Global Position System), foi que possibilitou e impulsionou a
implementação da agricultura de precisão, já que a criação de mapas, o conhecimento
geográfico de cada área e a localização das máquinas durante o as operações, são peças
fundamentais, tanto para a atuação, como para a gestão na lavoura. Nota-se também, que
desde o início da utilização foram impressos esforços no sentido de melhorar a precisão da
localização e a confiabilidade do GPS. Como por exemplo, com a utilização de correção
diferencial em tempo real, "barras de luz", que auxiliavam a aviação agrícola e outras
técnicas que exigiam receptores de GPS muito específicos, por vezes incompatíveis com os
controladores utilizados. Portanto é possível inferir que o estudo na área de navegação
com estimativa de posição e orientação são muito importantes para esse setor, e uma das
formas estudadas atualmente é a fusão do receptor de GPS com os sinais dos sensores
inerciais de uma IMU (Inertial Measurement Unit), formando um sistema inercial de
auxilo à navegação, INS (Inertial Navegation System) (INOUE, 2012; FARRELL, 2008).
Sendo o Brasil um país com grande potencial para se tornar um expoente na
agricultura mundial, acrescido do grande uso da rede CAN em máquinas agrícolas e aliado
1.2. Objetivos 21

ao papel fundamental das informações sobre posicionamento e orientação de máquinas


agrícolas em campo, esse projeto de conclusão de curso visa compartilhar os sinais de um
receptor GPS e de uma IMU em uma rede CAN para a estimativa de posição e orientação
de um veículo agrícola. E vislumbrar possíveis aplicações na área de agricultura de precisão.

1.2 Objetivos
Este trabalho tem como objetivo principal o estudo do protocolo CAN e sua
aplicação nas máquinas agrícolas, bem como possibilitar ao aluno o contato com os
sensores inerciais da IMU e do receptor de GPS, desenvolvendo o tratamento inicial dos
dados brutos fornecidos por esses sensores diretamente no firmware das ECUs (Electronic
Control Unit) conectadas a rede.
De encontro com esse objetivo, procura-se desenvolver uma plataforma de testes
de uma rede CAN onde esses sensores são conectados e realizam a comunicação com
uma central conectada ao computador. Com esse desenvolvimento tem-se os objetivos
de, estudar todos os requisitos de implementação de uma rede nesse protocolo, desde a
especificação dos circuitos integrados e a topologia da rede, passando pelo desenvolvimento
do software embarcado e as condições de funcionamento do protocolo, chegando até ao
estudo da latência das mensagens, a melhor forma de realizar o tratamento dos dados e a
priorização das mensagens.
23

2 Arquitetura da eletrônica embarcada e con-


ceitos de rede

Eletrônica embarcada, de maneira geral, são chamados as formas de conexão e


implementação de diversos mecanismos de medição e controle em um determinado sistema
embarcado (GUIMARÃES, 2003). E considerando o crescimento da presença de sistemas
eletrônicos, instrumentação inteligente e controle distribuído em automóveis, máquinas
agrícolas, aeronaves, robôs, e sistemas embarcados de modo geral, torna-se importante
avaliar como esses diversos dispositivos são interconectados, quais são as ações necessárias
para realizar a manutenção e atualização do sistema, e como os dados gerados por eles
são armazenados, processados e protegidos de erros e ruídos. Portanto, nessa seção será
apresentado, o conceito de arquitetura centralizada e distribuída bem como suas vantagens
e desvantagens e por fim alguns conceitos básicos de rede que serão utilizados neste trabalho
como o modelo de referência OSI, o conceito de fieldbus e protocolo de comunicação.

2.1 Arquitetura centralizada


O sistema convencional, que tem sido muito utilizado em diversas aplicações é a
arquitetura centralizada, também chamado de não multiplexado (MARQUES, 2004), onde
uma única ECU central fica responsável pela leitura de todas as entradas, e o controle
de todas as saídas. Neste tipo de sistema, os sinais gerados por cada um dos sensores
existentes na aplicação é transmitido individualmente até a central, onde será processado.
Assim como as saídas, que são todas acionadas diretamente pela única ECU existente no
sistema.
O diagrama da Figura 2 apresenta um esquema típico da arquitetura centralizada,
onde os dispositivos são ligados em uma estrutura ponto a ponto, indo de onde estão
instalados fisicamente até a central. Por exemplo, no caso em que se deseja disponibilizar
os dados de medida de velocidade de um encoder fixado na roda de um implemento, será
necessário ligar o encoder através de um conjunto de fios até a central de processamento
localizada na cabine do trator.
Esta arquitetura possui as vantagens de um hardware mais simplificado, uma vez que
apenas um elemento do sistema necessita de programação e os demais elementos, sensores
e atuadores com seus respectivos cabeamentos, enviam ou recebem dados a todo momento
que o sensor disponibilizar ou a ECU central enviar comandos para os atuadores, sem a
necessidade de lógicas de varredura ou latência de transmissão e recepção de dados. Por
outro lado, apresenta uma grande quantidade de cabeamento, com diferentes especificações
24 Capítulo 2. Arquitetura da eletrônica embarcada e conceitos de rede

Figura 2 – Representação de uma arquitetura centralizada

dependendo do tipo de sensor ou atuador e além disso apresenta uma limitação de expansão,
já que a central é limitada em capacidade física e lógica (GUIMARÃES, 2003).

2.2 Arquitetura distribuída


Uma outra forma de se projetar um sistema com eletrônica embarcada é a chamada
arquitetura distribuída, ou sistema multiplexado (MARQUES, 2004), neste caso ECUs
inteligentes estão distribuídas por toda a aplicação, sendo cada uma responsável por
parte dos dados e do controle, normalmente, que estão fisicamente próximos a ela, ou que
pertençam ao mesmo conjunto de informações, por exemplo, uma ECU responsável pela
instrumentação do motor, ou pelas luzes dianteiras do veículo.

Figura 3 – Representação de uma arquitetura distribuída


2.3. Sistemas embarcado na agricultura de precisão 25

Na Figura 3 é ilustrado um sistema com arquitetura descentralizada, onde pode


ser visto diversas ECUs, sendo que neste caso possui uma que desempenha um papel de
central, mas está ligada ao mesmo barramento das demais, e outras que possuem entradas e
saídas ponto a ponto, mas que estariam próximas ao locais dos elementos a ela conectadas.
Como vantagens dessa arquitetura pode-se citar, o cabeamento reduzido, possibi-
litado pela instalação da ECU próxima aos sensores e atuadores e com a comunicação
entre eles sendo realizada por um barramento reduzido, ampla capacidade de expansão do
sistema, já que para inserir novos elementos basta configurá-los adequadamente e conectar
ao barramento, possibilita a utilização de protocolos inteligentes, que pode aumentar a
confiabilidade do sistema, "modularização"do projeto, que pode gerar interoperabilidade
entre os fabricantes, podendo facilitar a validação do sistema já que cada módulo pode ser
validado de maneira independente, antes de ser integrado a rede (GUIMARÃES, 2003).
Porém, esta arquitetura exige um software de controle da rede, o que acarreta um
incremento na complexidade do projeto, sendo o protocolo escolhido intimamente ligado
ao quanto esse incremento será significativo, outro fator encarado como uma desvantagem
desse método, é a determinação da taxa de transmissão ideal para cada aplicação, já que
esse dado influencia diretamente no desempenho do sistema, na escolha dos componentes
e no custo de implementação.

2.3 Sistemas embarcado na agricultura de precisão


Na agricultura de precisão a utilização de equipamentos para monitoramento e
controle, aliado a necessidade de dados rastreáveis, capazes de alimentar os sistemas de
gerenciamento da lavoura, são essenciais. Além disso é importante que os equipamentos
sejam de fácil manutenção, com interoperabilidade entre os fabricantes, para que o sistema
não se torne inoperante caso ocorra algum problema com um dos dispositivos ou fabricantes
(GUIMARÃES, 2003).
É importante notar que no campo os sistemas estão instalados em veículos em
movimento, que trafegam sobre terrenos irregulares, com poeira, umidade e extremos
de temperatura, além dessas condições, o implemento e o trator são frequentemente
desconectados e reconectados em diversas configurações (STRAUSS, 2001).
Assim, torna-se uma grande questão a quantidade e complexidade dos cabos
utilizados nas conexões dos diversos dispositivos embarcados. Segundo Strauss (2001), é
comum encontrar sistemas que misturam sensores analógicos com informações digitais
e conectores diferentes para cada tipo dispositivo. Resultando em um sistema de difícil
manutenção, com elevado risco de falhas e danos tanto mecânicos como de ruídos elétricos.
Com isso, nota-se que a utilização de uma arquitetura descentralizada com trans-
26 Capítulo 2. Arquitetura da eletrônica embarcada e conceitos de rede

missão digital de sinais, com protocolo de rede que possibilitem a detecção e correção
de falhas, bem como a diminuição desses problemas com cabeamento é extremamente
necessário e a CAN tem sido uma tendência (SOUSA, 2002; INAMASU, 2013).

2.4 Conceitos básicos em redes de comunicação


A definição de alguns termos e conceitos básicos sobre redes de comunicação se
tornam importantes para a discussão e correto entendimento dos itens que se seguirão
neste trabalho.
O modelo de referencia OSI (Open Systems Interconnection) é baseado na proposta
da ISO (International Starndards Organization), que busca direcionar os protocolos de
rede para uma padronização internacional. Este modelo trata da interconexão de sistemas
abertos, ou seja, dos sistemas que de alguma forma realizam uma comunicação com outros
sistemas . A grande característica do modelo OSI é a divisão e especificação de sete
camadas de rede. É importante salientar que um determinado protocolo, não precisa
necessariamente especificar todas as sete camadas. Essas camadas são denominadas por
camada física, de enlace dos dados, rede, transporte, sessão, apresentação e aplicação,
começando pela especificação do barramento elétrico na rede, chegando até a mais abstrata
delas (TANENBAUM, 2003).
O termo fieldbus é tradicionalmente utilizado para definir as redes digitais seriais
multiponto de conexão entre os dispositivos de campo, como sensores e atuadores, e
os sistemas de controle, como computadores industriais, controladores programáveis e
terminais de supervisão . Com o tempo, esse conceito se expandiu para outras áreas
além das indústrias e tem sido aplicado para todas as redes com controle distribuído e
transdutores inteligentes (SOUSA, 2002).
Tanenbaum (2003) de maneira sucinta, apresenta outra definição importante a ser
realizada largamente utilizada em redes de comunicação das mais diferentes naturezas. O
conceito de protocolo de comunicação, que entende-se pelo acordo entre as partes de como
será dada a comunicação, definindo um conjunto de regras entre elas, destaca-se também
que a violação do protocolo dificultará a comunicação ou até a tornará impossível.
27

3 A rede CAN

A rede CAN - Controller Area Network ou Rede de Área de Controle, pode ser
categorizada como uma rede do tipo fieldbus, desenvolvida na década de oitenta por Robert
Bosch para interconexão entre dispositivos dos automóveis leves. Porém, em pouco tempo
este padrão foi levado para outras áreas de aplicação como caminhões, ônibus, barcos,
satélites, máquinas agrícolas, de construção civil e militares, além de outros padrões nas
áreas de automação industrial, robótica e instrumentação médica (SOUSA, 2002).

Figura 4 – Camadas da rede CAN. Adaptado de: Bosch Gmbh (1991).

Em Bosch Gmbh (1991) é apresentado o protocolo CAN divido em três camadas,


física, objeto e transporte, como mostra a Figura 4. As camadas de objeto e de transferência
são equivalentes a camada de enlace de dados do modelo OSI.
Com o surgimento de novas aplicações e a relativa limitação do protocolo básico,
outros protocolos foram propostos para cada aplicação, contemplando as mais diversas
áreas, definindo novos conceitos para as camadas existentes e implementando outras
camadas do modelo OSI. Exemplos importantes são, o DeviceNet para aplicações em
automação industrial,o ISO 11783 ou ISOBus para aplicações na área agrícola, o CANOpen
como uma proposta de protocolo aberto, além de outros protocolos com características
especiais de tempo e codificação, na tentativa de melhorar o desempenho da rede em
termos de velocidade e confiabilidade, podendo citar o TTCAN (Time-Triggered CAN) e
28 Capítulo 3. A rede CAN

o FTT-CAN (Flexible Time-Triggered CAN) (FERREIRA; FONSECA, 2011; Di Natale


et al., 2012)
O CAN é um padrão baseado no paradigma de orientação a mensagem (SOUSA,
2002), o que significa que os dispositivos conectados a rede, denominados por nós, não
possuem endereço, mas são as mensagens que possuem o seu próprio identificador específico,
ou seja, considerando um nó de telemetria de um motor, ao invés desse nó possuir um
identificador, na verdade cada uma das informação geradas por ele é que possui um
endereço, por exemplo, a temperatura tem o endereço 0x10, o nível de óleo tem endereço
0x22 e assim por diante. Porém vale destacar, que cada protocolo, baseado no CAN, define
o endereço das mensagem de uma maneira diferente, sendo assim existem protocolos que
definem um endereço para cada tipo de dispositivo ou grupo deles dentro de uma rede.
No documento das especificações básicas (Bosch Gmbh, 1991) da CAN a Bosch
enumera alguns características encontradas nesse protocolo.

• priorização de mensagens - cada mensagem possui um identificador e o valor


deste determina a prioridade dessa mensagem sendo que quanto menor o valor maior
a prioridade.

• garantia de latência máxima - sabendo o número máximo e um projeto adequado


da rede no que diz respeito a prioridades.

• configuração flexível - como apenas as mensagens possuem um identificador, e


não o dispositivo, a remoção ou adição deste na rede é feita sem a necessidade de
reconfiguração de nenhum outro dispositivo da rede.

• recepção multicast com sincronização pelos bits - na camada de enlace é


possível que cada dispositivo filtre as mensagens recebidas aceitando apenas aquelas
com identificador de seu interesse, assim a comunicação pode acontecer para um grupo
específico dentro de uma mesma rede (conceito de multicast segundo Tanenbaum
(2003)).

• sistema com alta consistência - o protocolo busca garantir que todos os nós
recebam as mensagens, ou nenhum nó recebe, caso essa mensagem contenha algum
erro, isso é feito através das sinalizações de erro.

• multi-mestre - na CAN um mesmo nó pode ser mestre ou escravo dependendo de


sua prioridade e da estrutura de projeto da rede.

• detecção e sinalização de erro - mensagens e nós que apresentem alguns deter-


minados erros são reconhecidos pelos dispositivos e o erro é sinalizado para todos os
outros nós (detalhes desse processo serão descritos na seção de erros).
3.1. Camada física 29

• retransmissão automática de mensagens corrompidas assim que o barra-


mento esteja livre - assim que os erros são detectados existe um mecanismo para
retransmitir porém com limitação de tentativas.

• distinção entre erros temporários e permanentes com desconexão auto-


mática dos nós defeituosos.

3.1 Camada física


De maneira geral, a camada física no modelo OSI é responsável por definir as
características de bits na rede, como temporização, sinalização, níveis de sinal e a maneira
que esses bits vão ser transmitidos, como fios ou sem fio, conectores e todas as questões
ligadas ao meio físico de transmissão. Na norma CAN da Bosch a descrição da camada física
fica limitada a definição da temporização, codificação e sincronização dos bits, sendo que as
demais características, como conectores e os níveis dos sinais, não são cobertas pela norma
(Di Natale et al., 2012). Com isso surgiram outras normas que cobriam essas especificações,
as principais são da própria ISO e da SAE (Society of Automotive Engineers), sendo
importante destacar, a ISO 11898-2 High Speed a mais utilizada com velocidade de até
1Mbps e comprimento de 40m em teoria, a ISO 11897-3 Fault Tolerant com velocidade de
125kbps com uso de no máximo 32 e comprimento dependendo da carga no barramento, a
SAE J2411 Single Wire com a utilização de um único fio não blindado com velocidade
máxima de 33.3kbps e a SAE J1939 com suas características físicas expressas na Tabela 1,
essa norma além das especificações da camada física, também são definidas as outras seis
camadas do modelo OSI sendo assim considerado um protocolo de alto nível (Di Natale et
al., 2012; FERREIRA; FONSECA, 2011). Esse protocolo foi concebido para aplicações
em veículos pesados como ônibus e caminhões e serve de base para o principal protocolo
utilizado na agricultura.

Tabela 1 – Características físicas da norma SAE J1939. Adaptado de: Di Natale et al.
(2012).

Item Definição
Barramento Par Diferencial
Arbitragem de acesso a rede Aleatório, não destrutivo, bit dominante
Velocidade 250kbps
Máximo de nós 30
Topologia Barramento linear
Comprimento do tronco 40m
Comprimento da derivação 1m
Terminação 2
Cabo Par trançado blindado ligado ao terra
Conector 3 pinos não blindado
30 Capítulo 3. A rede CAN

Apesar dessas limitações impostas pela norma J1939, a ISO 11898, muito difundida
entre os fabricantes de circuitos integrados voltados ao CAN, apresenta a Tabela 2, com
regras práticas sobre o comprimento do barramento em função da taxa de transmissão.

Tabela 2 – Regras práticas da norma ISO 11898 para comprimento do barramento em


função da taxa de transmissão. Adaptado de: Ferreira e Fonseca (2011).

Taxa de Transmissão Comprimento[m]


1Mb/s 30
800kb/s 50
500kb/s 100
250kb/s 250
125kb/s 500
62.5kb/s 1000
20kb/s 2500
10kb/s 5000

3.1.1 Codificação dos bits e níveis de sinal


No nível da camada de rede o protocolo CAN usa uma codificação de bit chamada
de Non Return to Zero (NRZ), nesta codificação o sinal elétrico permanece constante por
todo o período do bit, diferente de outro tipo de codificação como a Manchester, onde
o sinal inverte durante o período, sendo então reconhecida a borda. Além disso, o CAN
utiliza uma regra de violação de bits chamada Bit-Stuffing (CiA, 2002).
A técnica de bit-stuffing no caso da CAN, considera como erro de transmissão
quando mais de cinco bits consecutivos forem idênticos. Assim, a cada seis bits é possível
prever qual o valor esperado, além disso essa regra é importante para a ressincronização
dos nós.
No CAN os níveis dos sinais elétricos seguindo a norma ISO 11898-2 são repre-
sentados por, recessivo (usualmente lógico 1) e dominante (usualmente lógico 0) . Assim
quando os dois sinais são aplicados no barramento o sinal dominante é que permanece,
isso é o que possibilita o mecanismo de acesso ao meio utilizado pela CAN discutido na
Seção 3.2.3 Mecanismo de acesso ao meio (Di Natale et al., 2012; SOUSA, 2002).
Como ilustrado na Figura 5 são considerados duas linhas de transmissão (CAN L e
CAN H), o nível de tensão elétrica especificado para o bit recessivo é de 2.5V, portanto com
uma tensão diferencial próxima de zero, sendo tolerado um valor mínimo de 0.55V para a
saída e máximo de 1.5V para a entrada. Já para o bit dominante a linha CAN L deve estar
com 1.5V e a linha CAN H com 3.5V, portanto uma tensão diferencial de 2V sendo tolerado
um valor mínimo de 1.5V para a saída e máximo de 4.1V para a entrada. A utilização
de sinais diferenciais é chamada de linha balanceada e juntamente com o par trançado
aumenta a robustez da comunicação, minimizando as interferências eletromagnéticas, já
3.1. Camada física 31

Figura 5 – Níveis dos Sinais Elétricos ISO 11898-2. Retirado de: Di Natale et al. (2012)

que assim os ruídos que interferem igualmente nas duas linhas manterão a tensão diferencial
(Di Natale et al., 2012).

3.1.2 Temporização dos bits e sincronização


Para garantir a integridade da comunicação com todos os nós lendo o mesmo valor
no barramento, o primeiro fato é que o tempo de transmissão do bit deve ser grande o
suficiente para que a propagação do sinal alcance ocorra do transmissor até o receptor e
volte ao transmissor(CiA, 2002).

Figura 6 – Tempo de bit nominal. Adaptado de: Di Natale et al. (2012)

Para tanto, o tempo de bit é dividido quatro seguimentos (Bosch Gmbh, 1991; Di
Natale et al., 2012):

• Segmento de Sincronização (SYNC SEG) - é uma referencia para a sincroni-


zação, a borda marca esse seguimento;
32 Capítulo 3. A rede CAN

• Segmento de Propagação (PROP SEG) - é utilizado para compensar o atraso


de propagação físico no barramento;

• Segmento 1 e 2 de Buffer de Fase (PHASE SEG1 e PHASE SEG2) - são


utilizados para compensar o erro de fase do bit podendo ressincronizar a posição do
segmento de sincronização.

Outra parte importante que pode ser visto na Figura 6 é o ponto de amostragem
(SAMPLE POINT), é nesta seção que efetivamente o nível (dominante ou recessivo) é lido
do barramento.
Todos esses segmentos são múltiplos de uma unidade predefinida de tempo chamada
de quantum que deriva diretamente no oscilador utilizado na aplicação depois de um
prescale, assim no momento de configurar ou projetar uma aplicação de CAN é muito
importante, para definir a taxa de transmissão, conhecer esse parâmetro.
Cada um dos segmentos possui um comprimento em função do quantum:

• SYNC SEG - 1 quantum;

• PROP SEG - programável de 1 a 8 quantum;

• PHASE SEG1 - programável de 1 a 8 quantum;

• PHASE SEG2 - é o máximo do PHASE SEG1 e o tempo de processamento.

O tempo de processamento é menor ou igual a 2 quantum e o número total de quantum


no tempo de bit deve ser entre 8 e 25 (Bosch Gmbh, 1991).

3.2 Camada de enlace


Lembrando que na especificação da Bosch essa camada do modelo OSI é definida
em função de duas outras camadas, a camada de transferência e a camada de objeto.
Portanto é importante que neste momento se defina com mais clareza cada uma dessas
camadas.
A camada de transferência segundo Bosch Gmbh (1991) representa o kernel(núcleo),
do protocolo CAN. Essa camada é responsável por apresentar as mensagens recebidas
da camada de objeto e enviar as mensagens para a camada de objeto. Também fica a
cargo desta camada a temporização de bit e sincronização, além de aplicar o quadro nas
mensagens, arbitragem das prioridades, acknowledgement (confirmação e reconhecimento),
detecção e sinalização de erros e confinamento das falhas. Fica então a cargo da camada de
objeto, filtrar as mensagens segundo seus identificadores, assim como determinar o estado
do nó e o tratamento das mensagens em transito.
3.2. Camada de enlace 33

Existem duas versões do protocolo CAN especificadas pela Bosch, o Padrão denotado
por CAN 2.0A e o Estendido denotado por CAN 2.0B. Estes diferem unicamente pelo
comprimento do identificador das mensagens, no primeiro caso é composto por 11 bits e
no segundo são adicionados mais 18 bits, totalizando um identificador de 29 bits (Bosch
Gmbh, 1991).

3.2.1 Tipo de quadros da mensagem CAN


No CAN as mensagens são especificadas com quatro tipos diferentes de quadros,
definidos de acordo com o conteúdo e a função de cada um (Di Natale et al., 2012).

1. Quadro de Dados - utilizado para fazer a transmissão de dados do nó de origem


para o destino.

(a) CAN 2.0a.

(b) CAN 2.0b.

Figura 7 – Quadro de dados Fonte: Sousa (2002).

Nas duas versões do CAN o quadro de dados é capaz de transmitir de 0 a 8 bytes,


o que diferencia é principalmente o tamanho do identificador, sendo que na versão
padrão (Figura 7a) este é formado por 11 bits e no estendido (Figura 7b) por 29
bits, além disso na versão estendida o bit IDE faz parte do campo de arbitragem
e é substituído por um bit reservado (r1) e nesse mesmo campo é adicionado o bit
SRR (Substitute Remote Request que deve ser sempre recessivo para que o quadro
estendido tenha prioridade mais baixa que o padrão. Os demais campos que podem
ser vistos na Figura 7 são (Di Natale et al., 2012; SOUSA, 2002; Bosch Gmbh, 1991):
34 Capítulo 3. A rede CAN

a) SOF Field (Start of Frame Field Campo de Início do Quadro): sinaliza o início
do quadro, formado por um bit dominante.
b) Arbitration Field Campo de Arbitragem: este campo contém o identificador e o
bit RTR (Remote Transmission Request) que quando é igual a zero indica que
o quadro é do tipo de dados e um quando é um quadro remoto.
c) Control Field (Campo de Controle): seis bits com o primeiro indicando se
é o quadro é padrão ou estendido, o seguinte (r0) é um bit reservado para
ampliações do CAN. E os quatro últimos (DLC Data Length Code) informam a
quantidade de bytes do campo de dados.
d) Data Field (Campo de Dados): possui 8 bytes (64bits) e sendo os primeiros bits
os mais significativos.
e) CRC Field (Cyclic Redundance Check Campo de Verificação de Redundância
Cíclica): utilizando os bits dos quatro primeiros campos é calculado com um
polinômio o código de 15 bits do CRC, com isso os receptores podem deduzir
se houve erro na transmissão, esse campo possui ainda um décimo sexto bit
recessivo delimitador.
f) ACK Acknowledge Field (Campo de Confirmação): é enviado um bit recessivo
que os receptores sobrescrevem com um dominante para indicar o recebimento
e um bit recessivo delimitador.
g) EOF Field (End of Frame Field Campo de Termino de Quadro): sinaliza o fim
do quadro e é composto por sete bis recessivos.

2. Quadro Remoto - utilizado para solicitar um quadro de dados com o mesmo


identificador enviado. A Figura 8 mostra o formato do quadro, este difere do quadro
de dados apenas por não conter o campo de dados, sendo o bit RTR sempre recessivo
e o campo DLC pode ser qualquer entre 0 e 8.

Figura 8 – Quadro remoto CAN 2.0b. Retirado de: Sousa (2002).

3. Quadro de Erro - enviado toda vez que é detectado um erro, porém este não é
um quadro real com uma estrutura de bits dividida em campos, como os anteriores,
3.2. Camada de enlace 35

mas é um resultado da sinalização de erro quando detectada por um ou conjunto de


nós, detalhes sobre esse quadro serão tratados na Seção 3.2.2 Detecção, controle e
sinalização de erros.

4. Quadro de Sobrecarga - empregado no controle de fluxo, utilizado para solicitar


mais tempo depois de um quadro de dados ou remoto, prevenindo que outra trans-
missão se inicie. Esse quadro é composto por uma sequencia de seis bits dominantes
iniciados durante o espaço entre os quadros, após esse envio, os demais nós da rede
enviam sinalizadores de sobrecarga, indicando que receberam a solicitação.

3.2.2 Detecção, controle e sinalização de erros


Sendo a rede CAN uma rede de campo e que busca manter a integridade das suas
comunicações, existem alguns mecanismos de detecção e controle de erros, com a finalidade
de manter o correto funcionamento do barramento como um todo.
Todo o controle de erros em cada nó se baseia em dois contadores: o REC (Receiver
Error Counter) e o TEC (Transmite Error Counter), o primeiro que acumula erros de
recepção e o segundo os erros ocorridos na transmissão. O protocolo define cinco tipos de
erros que causam incremento desses contadores são eles: Bit Error, o bit enviado pelo nó,
é diferente do lido por ele na rede, não sendo considerado erro de arbitragem; Stuff Error,
quando mais de cinco bits iguais são transmitidos, violando a regra de Bit-Stuffing; Form
Error, ocorre quando um bit de valor já definido tem seu valor diferente, CRC Error, o
cálculo do CRC é diferente do recebido pelo nó, indicando erros na mensagem; ACK Error,
ou erro de confirmação, quando um nó que transmitiu não recebe nenhuma confirmação.
Os contadores são incrementados de 1 a 8 dependendo da gravidade do erro, e
são decrementados a cada transmissão sem erros. O valor desses contadores definem três
estados de erro possíveis para o nó assumir, esses são mostrados na Figura 9 .

Figura 9 – Estados de erros possíveis. Retirado de: Sousa (2002).

No estado de Error Active, o nó envia seis bits dominantes, causando assim uma
violação do bit-stuffing da rede, assim todos os outros nós detectam essa violação, descartam
36 Capítulo 3. A rede CAN

todos os dados recolhidos e transmitem um campo sinalizador de erro, porém um nó


neste estado continua em funcionamento normal sem qualquer restrição. Quando um nó
detecta que seus contadores estão acima de 127, ele entra no modo Error Passive, emite
novamente uma violação de bit-stuffing e começa a considerar que os erros na rede são
muito provavelmente causados por ele, portanto continua possível enviar e receber dados.
Porém todas as vezes que se detecta qualquer erro na rede, este nó causa uma violação de
bit-stuffing, considerando que este erro foi causado por ele. E por fim, quando o valor do
TEC excede 255 esse nó passa para o estado de Bus-off e fica completamente desligado da
rede, voltando para o modo de operação somente depois da reinicialização do controlador
do protocolo CAN do nó (SOUSA, 2002).

3.2.3 Mecanismo de acesso ao meio


Como a comunicação ocorre serialmente com compartilhamento do canal de co-
municação, é necessário utilizar um mecanismo de acesso ao meio, caso da rede CAN,
utiliza-se o CSMA/NDBA – Carrier Sense Multiple Access with Non-Destructive Bitwise
Arbitration (Acesso Múltiplo com Detecção de Portadora com Arbitragem Não Destrutiva
por Operação Lógica Bit-a-Bit). Ambos trabalham monitorando e enviado dados bit a
bit, o CSMA defini que para um nó transmitir este precisa aguardar o barramento ficar
livre além de verificar bit a bit durante o envio do identificador, se outro nó não iniciou a
transmissão ao mesmo tempo. Já o processo NDBA cuida para que não haja colisão de
dados, assim através da lógica "E"no barramento, um dispositivo consegue discernir se o
outro nó que iniciou a transmissão ao mesmo tempo tem um identificador menor que o
seu, se sim interrompe sua transmissão e passa a olhar a rede como um receptor.

Figura 10 – Exemplo do processo de arbitragem. Retirado de: Di Natale et al. (2012).

Assim com essa lógica define-se o processo de arbitragem do protocolo CAN. A


3.2. Camada de enlace 37

Figura 10 mostra um exemplo desse processo, onde três nós iniciam a transmissão, com
seus respectivos identificadores (0x15A, 0x3D2 e 0X1F6). Ao enviar o primeiro bit referente
ao seu identificador, todos os nós ainda tem condições de continuar a transmissão, a partir
do segundo bit o nó com identificador 0x3D2 se retira-se da transmissão e passa para a
condição de receptor, o mesmo acontece com o nó de identificador igual a 0x1F6, por fim o
nó com menor identificador no caso igual a 0x15A recebe o direito de enviar a mensagem
(Di Natale et al., 2012).
No nível de bits a sequencia acontece da seguinte maneira: quando o barramento
está desocupado os nós podem iniciar a transmissão, todos que desejem enviar uma
mensagem enviam um bit dominante para sincronização e em seguida enviam o bit do
seu identificador, ao mesmo tempo que monitoram o barramento, assim quando um nó
detecta a presença de um bit dominante, tendo enviado um recessivo entra no modo de
recepção e aguarda o próximo período de arbitragem (SOUSA, 2002; CiA, 2002).

3.2.4 Filtro e aceitação de mensagens


Todas as mensagens enviadas em uma rede CAN chegam a todos os nós já que os
identificadores são apenas nas mensagens e não nos nós, porém mensagens são filtradas
pelo hardware da CAN antes de serem processadas pela aplicação, passando apenas aquelas
de interesse para o dispositivo em questão. Isso confere à rede uma vantagem de velocidade
e eficiência de processamento. A Figura 11 mostra o exemplo de uma comunicação CAN
típica onde o processo de multicast é aplicado. Nesse exemplo a estação 2 que produz os
dados envia a todos as outras estações, porém somente as estações 1 e 4 tem os filtros
configurados para receberem a mensagem com esse determinado identificador (SOUSA,
2002; CiA, 2002).

Figura 11 – Ilustração do conceito de multicast. Retirado de: CiA (2002).

O processo de aceitação das mensagens pelos nós da rede ocorre pela configuração
de dois filtros, primeiro a máscara que define quais os bits do identificador da mensagem
recebida que serão analisados e passaram para o segundo o filtro de aceitação, que
contêm os valores dos bits que serão comparados com o identificador.
38 Capítulo 3. A rede CAN

Figura 12 – Máscara e filtro para mensagem CAN. Adaptado de: Di Natale et al. (2012).

Nos controladores CAN existem um ou mais buffers de recepção, com isso pode-se
ter mais de uma máscara ou filtro de aceitação. No caso do exemplo da Figura 12 tem-se
dois buffers de recepção, uma máscara e dois filtros de aceitação. Assim é possível perceber
que a mesma máscara seleciona para os dois filtros quais bits serão observados, sendo que
neste caso apenas o filtro 1 aceita a mensagem.

3.3 Limitações da CAN


Apesar de todas as estrategias utilizadas pelo protocolo padrão do CAN e das demais
regras provenientes de outras normas, o CAN ainda apresenta algumas limitações. Segundo
Ferreira e Fonseca (2011) a julgar pela larga utilização desse protocolo os desenvolvedores
reconhecem muitas potencialidades nele, porém ainda são encontrados limitações.
Em princípio seguindo todos os procedimentos de sinalização e identificação de
erros, qualquer quadro corrompido deve ser rejeitado por todos os nós da rede. Porém, em
Ruffino et al. (1998 apud FERREIRA; FONSECA, 2011) identificou alguns problemas
chamados de IMO (Inconsistent Message Omissions) omissão inconsistente de mensagens,
onde alguns nós recebiam mensagens corretas e outros não e de IMD (Inconsistent Message
Duplicates) duplicação inconsistente de mensagens, onde alguns nós recebiam a mesma
mensagem várias vezes outros apenas uma. Esses problemas estão ligados principalmente
ao atraso de propagação do sinal na rede e ao BER (Bit Error Rate) da CAN. Ruffino et al.
(1998 apud FERREIRA; FONSECA, 2011) desenvolveu algumas pesquisas com diferentes
valores de BER para avaliar o seu efeito no índices de IMO e IMD.

3.4 A CAN na agricultura


O CAN na área agrícola, vem se desenvolvendo e tomando forma internacionalmente
através da ISO 11783, também conhecida com ISOBus. Equipes chamadas de força tarefa,
vem sendo formadas e se reunindo periodicamente para desenvolver as diversas partes e
em conjunto com fabricantes e outras instituições buscam criar equipamentos compatíveis
3.4. A CAN na agricultura 39

com a norma, buscando a interoperabilidade dos sistemas, além de promover um padrão


robusto e que atenda as necessidades do setor.
Segundo (GUIMARÃES, 2003) a norma vem como um facilitador para o controle
e monitoramento futuro além de contribuir com o desenvolvimento da agricultura de
precisão.
41

4 Implementação da rede de testes

Para aplicação dos conceitos do protocolo CAN e possibilitar um contato inicial com
os passos de projeto para um sistema com esse protocolo, foi proposto o desenvolvimento
e a construção de um protótipo de uma rede CAN para estimativa de orientação e posição
através de um sistema de navegação inercial auxiliado por um receptor GPS.
A proposta desse desenvolvimento considerou alguns requisitos, pode-se destacar:

• Ter ao menos três ECUs conectadas à rede;

• As ECUs deveriam ser: uma que enviaria mensagens de um receptor de GPS, uma
com mensagens dos sensores da IMU e outra ligada ao computador para receber os
dados;

• As ECUs com GPS e com IMU deveriam fazer o tratamento inicial dos dados brutos
dos sensores antes de enviá-los pela rede, afim de diminuir o tráfego na rede;

• No tratamento dos dados a ECU deveria ser capaz de interpretar o padrão de


comunicação do sensor e converter os dados para variáveis adequadas para cada tipo
de dado.

Com relação aos dados que devem ser enviados pela rede foram considerados aqueles
importantes para a navegação inercial e localização geográfica em unidades móveis. Assim
foram definidos, para o GPS:

• Latitude, Longitude e Altitude com decimal completo disponível pelo receptor;

• Velocidade;

• UTC (Universal Time Coordinated) Tempo Universal Coordenado em segundos;

• Curso e número de satélites disponíveis.

E para a IMU todos os disponíveis sendo eles:

• Dados do acelerômetro nas três coordenadas (x,y e z);

• Dados do giroscópio nas três coordenadas;

• Dados do magnetômetro nas três coordenadas.


42 Capítulo 4. Implementação da rede de testes

4.1 Topologia geral da rede


Considerando os requisitos propostos para a rede foi desenvolvida uma topologia
para o protótipo da rede de testes como mostra a Figura 13.

Figura 13 – Topologia do protótipo da rede de testes.

Pode-se observar que o projeto de cada uma das ECU’s vai ter um hardware
bastante semelhante, já que as interfaces são basicamente as mesmas, passando de USART
(Universal Synchronous Asynchronous Receiver Transmitter) (Transmissor Receptor Uni-
versal Síncrono e Assíncrono) para CAN. A principal diferença está no código embarcado,
que faz a leitura de padrões totalmente distintos de cada um dos sensores, realizando o
parse dos dados separando os dados de interesse e reconstituindo-os na mensagem de envio
para o computador.
Outro ponto importante para o projeto e o correto funcionamento da rede foi o
desenvolvimento de um dicionário de dados para as mensagens apresentado na Tabela 3.
Este foi construído para a organização e sistematização das informações, sem utilizar
diretamente uma padronização especificada em norma, porém foi utilizado como base o
dicionário apresentado em GUIMARÃES (2003).

Tabela 3 – Dicionário de dados da rede.

ECU ECU ECU


# Descrição da Mensagem Repetição ID0 ID1
GPS IMU PC
1 UTC 1Hz TX - RX 0x50 0x40
1 Posição - Latitude e Longitude 1Hz TX - RX 0x51 0x40
2 Velocidade e Altitude 1Hz TX - RX 0x52 0x40
3 # Satélites 1Hz TX - RX 0x53 0x40
4 Curso 1Hz TX - RX 0x54 0x40
5 Acelerômetro (Ax,Ay,Az) 17Hz - TX RX 0x60 0x80
6 Giroscópio (Gx,Gy,Gz) 17Hz - TX RX 0x61 0x80
7 Magnetômetro (Mx,My,Mz) 17Hz - TX RX 0x62 0x80
4.2. Arquitetura genérica das ECUs 43

Cada linha na Tabela 3 representa uma mensagem que será disponibilizada na rede,
analisando essa tabela temos as seguinte informações:

• A frequência de repetição de cada mensagem é a mesma apresentada pelo próprio


sensor em questão, já que logo que este disponibiliza os dados, a ECU correspondente
faz o tratamento inicial dos dados e coloca na rede;

• O papel de cada ECU é especificado por mensagem, indicando se esta está enviando
a mensagem(TX), recebendo (RX) ou se a mensagem é indiferente para aquela ECU;

• O identificador de cada mensagem é especificado para garantir que a mensagem do


GPS tenha prioridade maior que a da IMU devido a frequência de repetição de cada
um.

4.2 Arquitetura genérica das ECUs


As ECUs desse projeto foram implementadas por um projeto com o microcontrolador
PIC 18F2580 da Microchip R
, o código embarcado foi desenvolvido na linguagem C
utilizando o compilador XC8 e o ambiente de desenvolvimento MPLABX R
, escolhidos
principalmente pela vasta bibliografia disponível em livros e online (IBRAHIM, 2014;
PEREIRA, 2003; RAJBHARTI, 2001) bem como a experiencia do autor com as ferramentas.
Em termos de hardware a arquitetura de cada ECU em uma rede CAN pode ser
realizada seguindo duas topologias diferentes como mostra Figura 14.

(a) Controlador CAN externo. (b) Controlador CAN interno.

Figura 14 – Topologias de ECU.

A arquitetura da Figura 14a utiliza um controlador CAN externo ao microcon-


trolador onde o código principal da ECU está, exigindo uma comunicação entre estes
tipicamente com um protocolo serial, já na Figura 14b o controlador é um periférico
44 Capítulo 4. Implementação da rede de testes

interno ao microcontrolador. Para a primeira implementação, observa-se uma vantagem de


custo pois pode-se escolher um microcontrolador mais simples, porém com o controlador
interno o projeto da placa torna-se mais simples e um sistema mais compacto, reduzindo
falhas com conexões importante para aplicações em ambientes extremos como o caso da
agricultura. Obtêm-se também um ganho de velocidade e eficiência do código, já que não
são necessárias rotinas extras para o envio dos dados ao buffer de transmissão nem para a
leitura na recepção.
Apesar de cada ECU ter uma função distinta na rede e tratar com dados diferentes,
buscou-se desenvolver um mesmo esquema elétrico para todas, afim de simplificar o desen-
volvimento do sistema e padronizar o projeto, visando expansões futuras e substituições.
Cada ECU possui as seguintes especificações técnicas:

• Microcontrolador PIC18F2580 (MICROCHIP Technology Inc., 2009) que possui 28


pinos, conversor analógico digital de 10 bits, canal de PWM e controlador CAN
interno com suporte para CAN 2.0a e b (ECAN);

• Transceptor CAN MCP2551 (MICROCHIP Technology Inc., 2010) suporte para


comunicação até 1Mb/s;

• Cristal para o oscilador de 20MHz;

• Circuito conversor bidirecional de 3.3V para 5V, utilizado na adequação dos si-
nais de comunicação serial realizada entre os sensores (GPS e IMU em 3.3V) e o
microcontrolador (5V) (NXP Semiconductors, 2007).

• Terminador de 120Ω com ligação opcional por jumper.

Na Figura 15 é apresentado o esquemático e na Figura 16 a placa do circuito


aplicados nas ECUs.

4.2.1 Módulo ECAN do PIC18F2580


O módulo ECAN é uma interface serial que implementa todo o procolo definido
pela norma Bosch Gmbh (1991), suportando CAN2.0a e CAN 2.0b. Pode-se destacar as
seguinte características (MICROCHIP Technology Inc., 2009):

• Quadro de bits padrão e estendido;

• Filtro de dados com suporte para DeviceNetTM ;

• Taxa de transmissão configurável até 1MB/s;

• Seis modos são possíveis:


4.2. Arquitetura genérica das ECUs 45

Figura 15 – Esquemático do circuito utilizado para as ECUs.

– Configuração;
– Desabilitado;
– Operação Normal, com três outras categorias, modo 0 padrão, modo 1 estendido
com DeviceNetTM e modo dois First In First Out com DeviceNetTM ;
– Apenas Escuta, neste modo é possível receber mensagens com erros;
– Eco (Loop Back) com transmissão interna, sem necessidade de ligação física;
– Reconhecimento de Erro, diferente do modo de Apenas Escuta é possível enviar
mensagens nesse modo.

• Suporte aos quadros, padrão e estendido de dados, remoto, de erro, sobrecarga e


espaço em quadros automático;

• Buffers de transmissão e recepção configuráveis;

• Máscaras e filtros de aceitação configuráveis;

• Sinalização e detecção de erros automática.

Na folha de dados (MICROCHIP Technology Inc., 2009) é sugerida uma sequencia


de configuração do módulo:

• Colocar o módulo em modo de configuração e confirmar;


46 Capítulo 4. Implementação da rede de testes

Figura 16 – Placa do circuito utilizado para as ECUs.

• Selecionar qual o modo de operação desejado;

• Configurar os registradores da taxa de transmissão;

• Configurar as máscaras e os filtros de aceitação;

• Colocar o módulo no modo normal ou em outro modo desejado.

No caso do PIC18F2580 fisicamente o módulo utiliza os pinos 23 RB2/CANTX e


24 RB3/CANRX.
O periférico conta ainda com 3 buffers dedicados a transmissão e 3 a transmissão e
nos modos de operação normal 1 e 2 apresentam outros buffers configuráveis.

4.2.2 Transceptor MCP2551


O dispositivo MCP2551 MICROCHIP R
é responsável por implementar a camada
física, e realiza a interface entre a camada de controle de uma rede CAN e o meio físico.
Este dispositivo trabalha como um transceptor compatível com a norma ISO-11898, na qual
estão definidos os sinais elétricos presentes no barramento. O MCP2551 prove proteção e
isolação dos dispositivos lógicos de controle de eventuais danos provenientes da rede CAN
4.2. Arquitetura genérica das ECUs 47

como, transientes elétricos, descargas de energia estática ou interferências eletromagnéticas.


Fica a cargo deste dispositivo, gerar na rede o modo recessivo ou dominante para seu nó.
Existem também três modos de operação, selecionáveis através da corrente no pino 8 RS.
O modo High-Speed, selecionado quando o pino RS é ligado ao terra, executa a
transição dos sinais de CANH e CANL com a maior velocidade possível para barramentos
CAN de alta velocidade. Outro modo possível é o Slope-Control, onde é ligada em RS
uma resistência ligada ao terra que limita a corrente neste pino, com isso controla-se o
tempo de transição dos sinais, reduzindo os efeitos de interferência eletromagnética do
meio na comunicação, que é importante em ambientes muito ruidosos, ou em aplicações
muito sensíveis. E por fim o modo Standy, determinado pela aplicação de sinal alto no
pino de controle, este modo coloca o dispositivo em modo de baixo consumo, porém a
camada de controle ainda é capaz de receber os dados do barramento, sendo possível
então monitorar a rede e retornar o dispositivo para seu funcionamento normal caso seja
necessário. (MICROCHIP Technology Inc., 2010).

4.2.3 Conversor bidirecional

Sendo o microcontrolador utilizado com saídas no padrão TTL (Transistor-Transistor


Logic(0 a 5V) e os sensores utilizados com padrão LVTTL Low Voltage Transistor-Transistor
Logic (0 a 3.3V) foi necessário a utilização de um sistema de conversão, para adequação
desses nível de sinal.
Seria necessário um sistema capaz converter os sinais com velocidade suficiente
para uma comunicação serial USART e que pudesse fazer a conversão do nível mais alto
para o mais baixo e vice-versa, mesmo que em linhas diferentes, no caso foi escolhida uma
técnica utilizada em redes I2 C, que operam com taxas de transmissão de até 400kbps,
acima da maior taxa necessária nesse projeto dada pela IMU de 57.6kbps.
O projeto foi baseado nos conceitos apresentados em NXP Semiconductors (2007)
que utiliza um mos-fet N e dois resistores por linha como mostra a Figura 17.
Esse circuito funciona da seguinte maneira, quando nenhum dos lados está colocando
nível baixo na rede tanto o terminal de porta como de fonte do mosfet estão ligados ao
3.3V, o primeiro diretamente e outro pelo resistor, nesta condição o mosfet não esta
conduzindo mantendo então os dois lados em nível alto, com níveis de tensão diferentes.
Quando o lado de 3.3V coloca a linha em nível baixo o terminal de fonte do mosfet vai
para nível baixo também e como a porta mantem-se em alto o mosfet passa a conduzir e o
lado de 5V passa ao nível baixo também. E por fim, quando o sinal do lado de 5V coloca
a linha em nível baixo, faz o diodo formado pelo substrato do mosfet entrar em condução
levando o lado de 3.3V para o mesmo nível do outro lado (NXP Semiconductors, 2007).
48 Capítulo 4. Implementação da rede de testes

Figura 17 – Circuito do conversor de nível bidirecional. Retirado de: NXP Semiconductors


(2007).

4.3 ECU do GPS


No contexto de navegação e localização a utilização de receptores de GPS se torna
muito importante já que são capazes de fornecer informações sobre posição e velocidade.
Em geral, essas informações são transmitidas usando protocolo padrão NMEA(National
Marine Electronics Association) 0183, que apresenta diversos tipos de mensagens, contendo
dados de posicionamento, como latitude, longitude, altitude, número de satélites em vista
pelo receptor, dentre outros. O receptor de GPS utilizado nesse trabalho é o SKYTRAQ
Venus638FLP, fornecido pela SparkFun Electronics Inc., que oferece uma taxa padrão
de 1Hz e provê as mensagens GPGGA, GPGSA,GPGSV, GPRMC e GPVTG do padrão
NMEA 0183 (SKYTRAQ Technology Inc., 2008). A Figura 18 mostra uma foto da placa
de receptor utilizada.

Figura 18 – Placa receptor de GPS. Retirado de: SparkFun Electronics Inc. (2002).

A ECU do GPS utiliza estrutura genérica de rede proposta anteriormente, essa


ECU tem a função de receber os dados do receptor de GPS, reconhecer o padrão, filtrar os
dados de interesse e disponibilizá-los na rede segundo o dicionário de dados estabelecido.
4.3. ECU do GPS 49

Foi desenvolvido um firmware capaz de reconhecer as diferentes mensagens do


padrão NMEA 0183, neste trabalho foram utilizadas as informações mensagens GPGGA,
de onde foi retirado a latitude, longitude, UTC em segundos e número de satelites utilizados
e GPVTG de onde foi retirada a velocidade. Abaixo são apresentados um exemplo das
mensagens:

• $GPGGA,111636.932,2447.0949,N,12100.5223,E,1,11,0.8,118.2,M„„0000*02

• $GPVTG, 000.0,T„M,000.0,N,0000.0,K,A*3D

As Tabelas 4 e 5 mostram a descrição de cada campo da mensagem NMEA 0183


GPGGA e GPVTG.
Tabela 4 – Descrição dos campos da mensagem NMEA 0183 GPGGA. Modificado de:
SKYTRAQ Technology Inc. (2008).

# Descrição Formato
1 Tempo UTC hhmmss.sss
2 Latitude ddmm.mmmm
3 Indicador Norte/Sul N/S
4 Longitude dddmm.mmmm
5 Indicador Leste/Oeste E/W
6 Qualidade do GPS (modos) 0-8
7 Satélites Utilizados 00-12
8 HDOP 00.0-99.9
9 Altitude acima do mar mmm.c
10 Estação DGPS ID, distancias
11 Checksum 02

Tabela 5 – Descrição dos campos da mensagem NMEA 0183 GPVTG. Modificado de:
SKYTRAQ Technology Inc. (2008).

# Descrição Formato
1 Curso (graus) 000.0 - 359.9
2 Velocidade do chão (nós) 000.0 - 999.9
3 Velocidade do chão (km/h) 0000.0 - 1800.0
4 Modo de Operação carácter
5 Checksum 3D

Para o tratamento dessas mensagens foi desenvolvido um conjunto de estruturas e


funções, o código e a documentação completa estão disponíveis no Anexo ??.
O processo geral que ocorre no processamento das mensagens e armazenamento no
formato adequado para cada informação é da seguinte maneira:

1. Recebe um carácter do sensor via interrupção da USART;


50 Capítulo 4. Implementação da rede de testes

2. A função getGPSmenssage trata cada mensagem, transfere os buffers temporá-


rios para os definitivos de cada mensagem com o tipo carácter (char) e realiza a
confirmação da função;

3. Em seguida cada conjunto de informação possui uma função especifica que retira a
informação do buffer em carácter e converte para o tipo mais adequado para cada
dado, por exemplo, a informação de tempo UTC utiliza a função getGPSutc, que
recebe os dados armazenados nos buffers e retorna os valores inteiros de hora, minuto
e segundo e o valor em double da soma dos minutos e segundos em segundos.

Outro exemplo de função de processamento desenvolvida semelhante à do UTC


foi a getGPSpos que recebe os mesmos dados e retorna os valores em double de latitude e
longitude, já sinalizados dependendo da posição norte e sul, leste e oeste.
Após o processamento das mensagens e o armazenamento dos dados nas varáveis
especificas, esses devem ser disponibilizados na rede CAN. Porém mesmo que o protocolo
CAN possibilite o envio de 8 bytes (64 bits) de uma só vez e o módulo do microcontrolador
efetue essa operação, o que seria suficiente para enviar duas variáveis do tipo double em
uma única transação, o microcontrolador utilizado é de 8 bits e portanto o barramento
interno só possibilita a passagem de um byte por vez.
Para evitar a criação de outra função para separar os dados, foi utilizada uma
estrategia de criar uma união com três varáveis, um vetor com duas posições do tipo double
com trinta e dois bits cada uma, um vetor com três posições do tipo inteiro com dezesseis
bits cada um e um vetor com oito posições do tipo carácter com oito bits cada um. Assim
quando se armazena uma variável do tipo double é possível ler como três do tipo inteiro
ou oito do tipo carácter.
Isso é possível pois ao armazenar uma união, o compilador reserva apenas um
único espaço de memória com o tamanho da maior variável, no caso o vetor de double,
que no microcontrolador utilizado é igual a oito espaços de memória de oito bits, e ao ler
cada carácter do vetor da união, esta na verdade lendo um pedaço de oito bits das várias
double e o mesmo acontece com o inteiro. A Figura 19 mostra um esquema de como fica
organizado a memória e a divisão das variáveis descritos.
Utilizando essa estratégia, foi necessário apenas passar os dados já armazenados
para a estrutura e em seguida para cada um dos oito registradores do módulo ECAN do
microcontrolador.

4.4 ECU da IMU


A IMU é composta pelo conjunto de 3 sensores: acelerômetro, giroscópio e mag-
netômetro. Com as medidas destes sensores é possível obter uma estimativa de atitude e
4.4. ECU da IMU 51

Figura 19 – Esquemático da união na memória.

orientação da plataforma, ou seja, os ângulos de rolagem, arfagem e guinada. Uma UMI


capaz de fornecer todos os dados necessários é a 9DOF RAZOR da SparkFun Electronics
Inc., composta por um acelerômetro digital de 3 eixos (ADXL345), um giroscópio de 3
eixos (ITG-3200) e um magnetômetro de 3 eixos (HMC5883L), nesta placa além desses
sensores existe um microcontrolador que se comunica com os sensores em seus protocolos
e formata uma mensagem para envia via USART. Com este dispositivo, é possível optar
pela leitura dos dados brutos (sem filtragem) de cada um dos sensores na Figura 20,
mostra uma foto da placa da IMU utilizada.

Figura 20 – Placa da IMU. Retirado de: SparkFun Electronics Inc. (2002).

Diferente do receptor de GPS utilizado, que logo ao ser ligado começa a enviar os
dados, a IMU utilizada necessita de um processo de inicialização, que consiste em escolher
o modo de operação, neste trabalho será utilizado apenas o modo chamado RAW Data
onde é enviado uma única mensagem com os valores de cada um dos sensores formatados
da seguinte maneira:

• Exemplo de mensagem enviada: $-7,0,234,25,-41,-27,-42,-133,102#

• Descrição dos campos: $ax,ay,az,gx,gy,gz,mx,my,mz#

– ax,ay,az: dados do acelerômetro nos três eixos;


52 Capítulo 4. Implementação da rede de testes

– gx,gy,gz: dados do giroscópio nos três eixos;


– mx,my,mz: dados do magnetômetro nos três eixos.

Por ser uma única mensagem, comparando com o processo de recepção do GPS
a IMU apenas utiliza a função getIMUmessage para receber cada carácter do sensor via
USART salvar em um buffer temporário até o término da mensagem, salvar em um buffer
definitivo e sinalizar a recepção.
Em seguida são utilizadas três funções (getIMUacel,getIMUgiro,getIMUmagn) para
retirar da mensagem salva no buffer cada uma das informações dos sensores e salvá-las em
variáveis do tipo inteiro.
Novamente para o envio na rede CAN é utilizada a união descrita na seção anterior,
sendo assim o envio dos dados da IMU torna-se mais simples pois são enviados os três
eixos de cada sensor na mesma mensagem CAN.
A Figura 21 apresenta o fluxograma da ECU da IMU, onde a função e separar os
dados da mensagem e a de enviar os dados para a CAN, tem seus códigos apresentados
nos apêndices. Juntamente com a função principal ocorre a interrupção de recepção de
carácter da serial, que auxilia no controle de fluxo, como seu código também disponível na
seção de apêndices.

INÍCIO

Configurações
do PIC
2
1

Mensagem N IMU em N
nova? Reset?

S S
Separa os dados
da mensagem Envia
getIMUacel Configuração
da IMU

Envia os dados na
CAN
ECAN_Transmit
1

Figura 21 – Fluxograma da função principal da IMU.


4.5. ECU computador 53

4.5 ECU computador


A ECU do computador possui a estrutura de hardware semelhante a arquitetura
genérica descrita, a única diferença é que dispensa a utilização do conversor, pois não
existe sensor conectado a ela.
Essa tem na rede a função de receber os dados enviados pelos outros nós via CAN,
filtrá-los e formatá-los para serem enviados ao computador através de um conversor de
USART/TTL para USB (Universial Serial Bus), onde serão monitorados por uma aplicação
no software MatLab R
.
Portanto foi desenvolvido um firmware para essa ECU que possibilitasse essas
funcionalidades sendo capaz então de:

• Estabelecer comunicação com a rede CAN com a configuração do módulo ECAN do


microcontrolador;

• Reconhecer o dicionário de dados, para filtrar as mensagens recebidas da maneira


correta;

• Enviar os dados recebidos pelo módulo USART;

• Reconhecer os erros sinalizados pelo módulo ECAN e apresentar no computador.


55

5 Avaliação da rede e resultados

Com o objetivo de avaliar o correto funcionamento da comunicação CAN entre as


ECUs, bem como o processamento dos dados dos sensores, foram realizados uma série de
testes, físicos e de software, apresentados a seguir.

5.1 Sinais elétricos da rede CAN


Foi realizada a análise dos sinais CAN L e CAN H presentes na rede implementada
variando o comprimento do barramento.
Na Figura 22, são apresentados os sinais CAN obtidos com um osciloscópio, para
que fosse possível visualizar o efeito de cancelamento do ruído, o teste foi realizado com
dois comprimentos do barramento diferentes, com 1,3 m é apresentado na Figura 22a
e com 2,1 m na Figura 22b. O barramento mais longo foi ligado próximo a uma fonte
chaveada para que o nível de ruído fosse maior.

(a) Cabo com 1,3m. (b) Cabo com 2,1m.

Figura 22 – Sinais CAN L e CAN H obtidos da rede implementada.

Nas figuras foram destacados alguns pontos notáveis, como o sinal dominante, o
sinal recessivo e o barramento livre.
É interessante notar o nível de ruído presente na linha livre nos sinais. Analisando
CAN L e do sinal CAN H e a tensão diferencial, observando o aumento do ruído no
barramento maior, porém no sinal diferencial não é observada nenhuma mudança.
56 Capítulo 5. Avaliação da rede e resultados

5.2 Monitoramento de erros


Utilizando o registrador COMSTAT do módulo ECAN, foi implementada uma
leitura de erro na rede, foram então realizados três testes afim de simular erros:

1. Retirar um terminador: indicação de erro 131 error active;

2. Retirar os dois terminadores: indicação de falha na recepção 139 error passive;

3. Retirar o fio CAN L do barramento : Sem indicação de erro;

4. Retirar o fio CAN H do barramento : interrupção total da transmissão.

5.3 Atraso nos dados


Foi realizado um teste para medir o tempo de atraso que a rede insere na transmissão
de uma mensagem CAN com oito bytes em uma rede com apenas duas ECUs e apenas
uma enviando mensagem.
Esse teste foi realizado enviando uma mensagem com dados de valor conhecido e ao
solicitar o envio passar um pino digital do microcontrolador conectado a um osciloscópio,
para o nível lógico um. Na ECU receptora ao receber os dados e confirmar que são os
dados corretos, sinaliza da mesma forma o osciloscópio.

Figura 23 – Medida de atraso da rede de testes.

Assim medindo o tempo entre os dois sinais foi obtido o atraso de 200 micro
segundos, como mostra a Figura 23 entre solicitar ao módulo ECAN o envio da mensagem
na ECU de transmissão, até os dados estarem disponíveis na ECU de recepção.
57

6 Considerações finais

6.1 Trabalhos futuros


Com o desenvolvimento dessa plataforma de testes e o conhecimento adquirido é
possível desenvolver, em um tempo menor, outras ECUs que executem diferentes funções,
como por exemplo o desenvolvimento de ECUs com atuadores como motores e outros
sensores como encoder. Podendo assim desenvolver uma plataforma de testes para o estudo
de controle distribuído em sistemas móveis, muito interessantes para aplicações como
piloto automático de máquinas agrícolas ou carros autônomos.
Outra melhoria que poderia ser realizada agora com uma plataforma inicial desen-
volvida é a implementação de um procolo mais específico, como o J1939 ou o próprio ISO
11783, que abrem para a rede muitas outras aplicações em sistemas mais complexos que
necessitem de abordagem com mais alto nível.

6.2 Conclusão
A utilização do protocolo CAN em máquinas agrícolas vem crescendo muito e
se tornando mais popular com novos fabricantes e produtos disponíveis, isso deve-se ao
protocolo possuir características que vem de encontro com as necessidades da área agrícola
no que diz respeito a sistemas móveis, pode-se citar algumas dessas características como,
barramento reduzido, robustez à ruído e problemas de desconexão acidental de dispositivos
ou inserção de novos. Outro fator determinante para o crescimento dessa aplicação é
a criação e fortalecimento de uma norma específica a ISO 11783, também conhecida
como ISOBus, que com as diversas forças tarefas, pesquisadores, empresas e instituições
envolvidas, vem contribuindo muito para aumentar a interoperabilidade entre fabricantes
o que incentiva a utilização por parte dos agricultores de produtos compatíveis com a
norma.
As pesquisas realizadas durante esse trabalho mostraram que a utilização do proto-
colo CAN em qualquer aplicação deve ser estudada a luz de uma norma mais direcionada
para a aplicação em questão. Isso é importante pois a norma do CAN especificada pela
Bosch, possui poucos detalhes de implementação principalmente das características ligadas
a camada física e da organização dos dados em um nível mais alto.
Foi observado também que a implementação do processamento das mensagens do
receptor de GPS e da IMU foram facilitados pela utilização da arquitetura distribuída, já
que dessa forma foi possível fazer a leitura dos dois sensores utilizando a interface padrão
58 Capítulo 6. Considerações finais

dos mesmos, a USART, caso contrário seriam necessários dois canais USART ou realizar a
leitura dos sensores de outra forma. Devido a alta taxa de transferência alcançada pela
rede CAN, quando comparada a taxa de atualização dos sensores conclui-se que a CAN
mostra-se promissora na utilização de estimativa de orientação e posição com sistemas
distribuídos.
59

Referências

Bosch Gmbh, R. CAN Specification. [S.l.], 1991. 72 p. Citado 7 vezes nas páginas 11, 27,
28, 31, 32, 33 e 44.
CiA. (CAN in Automation GmbH) - CAN Physical Layer and CAN Protocol.
Commerzbank, Nuremberg (Germany): [s.n.], 2002. Virtual. Disponível em:
www.can-cia.org. Acessado em: 11/2014. Citado 4 vezes nas páginas 11, 30, 31 e 37.
Di Natale, M. et al. Understanding and Using the Controller Area Network Communication
Protocol. New York, NY: Springer New York, 2012. Citado 10 vezes nas páginas 11, 13,
28, 29, 30, 31, 33, 36, 37 e 38.
FARRELL, J. Aided navigation: GPS with high rate sensors. [S.l.]: McGRaw-Hill
Companies, 2008. 553 p. Citado na página 20.
FERREIRA, J.; FONSECA, J. A. Universidade de Averio - Portugal. Controller Area
Network. In: The Industrial Electronics Handbook - Industrial Communication Systems. 2.
ed. Nova York: CRC Press, 2011. cap. 31, p. 413–426. Citado 5 vezes nas páginas 13, 28,
29, 30 e 38.
GUIMARÃES, A. D. A. Análise da Norma ISO 11783 e sua Utilização na Implementação
do Barrramento do Implemento de um Monitor de Semeadora. Mestrado — Escola
Politécnica da Universidade de São Paulo, 2003. Citado 5 vezes nas páginas 23, 24, 25, 39
e 42.
IBRAHIM, D. PIC Microcontroller Projects in C: Basic to Advanced. Segunda. Londres:
Elsevier, 2014. 550 – 574 p. Citado na página 43.
INAMASU, R. Y. Embrapa Instrumentação São Carlos. Padronização da Eletrônica
Embarcada em Máquinas Agrícolas. In: Boletim Técnico Agricultura de Precisão
Ministério da Agricultura, Pecurária e Abastecimento. 3. ed. Brasília: Biblioteca Nacional
de Agricultura (BINAGRI), 2013. p. 26–34. Citado 2 vezes nas páginas 19 e 26.
INOUE, R. S. Controle Robusto Descentralizado de Movimentos Coordenados de Robôs
Heterogênios. Doutorado — Escola de Engenharia de São Carlos Universidade de São
Paulo, 2012. Citado na página 20.
JUNTOLLI, F. V. Secretaria de Desenvolvimento Agropecuário e Cooperativismo.
Agricultura de Precisão no Brasil. In: Boletim Técnico Agricultura de Precisão Ministério
da Agricultura, Pecurária e Abastecimento. 3. ed. Brasília: Biblioteca Nacional de
Agricultura (BINAGRI), 2013. p. 36–38. Citado na página 19.
MARQUES, M. A. CAN Automotivo Sistema de Monitoramento. 150 p. Mestrado —
Universidade Federal de Itajubá, 2004. Citado 2 vezes nas páginas 23 e 24.
MICROCHIP Technology Inc. Data Sheet PIC18F2480/2580/4480/4580. [S.l.], 2009.
Citado 2 vezes nas páginas 44 e 45.
MICROCHIP Technology Inc. High-Speed CAN Transceiver MCP2551. [S.l.], 2010. 24 p.
Citado 2 vezes nas páginas 44 e 47.
60 Referências

MOLIN, J. P. U. d. S. a. P. E. S. d. A. L. d. Q. . Agricultura de Precisão. In: Boletim


Técnico Agricultura de Precisão Ministério da Agricultura, Pecurária e Abastecimento.
Brasília: [s.n.], 2013. p. 5–27. Citado 2 vezes nas páginas 19 e 20.

NISSEN, H. ISOBUS Status of Standardization and Implementation. Workshop ISOBus


Brasil, 2008. Citado 2 vezes nas páginas 11 e 19.

NXP Semiconductors. Level Shifting Techniques in I2C-bus Design. 2007. Citado 4 vezes
nas páginas 11, 44, 47 e 48.

PEREIRA, F. Microcontroladores PIC: Programação em C. Sexta. São Paulo: Érica, 2003.


358 p. Citado na página 43.

PEREIRA, R. R. D. Protocolo ISO 11783: Procedimentos para comunicação serial de


dados com o Controlador de Tarefas. 1–188 p. Mestre — Escola de Engenharia de São
CarlosUniversidade de São Paulo, 2008. Citado 2 vezes nas páginas 19 e 20.

RAJBHARTI, N. (Technology, Microchip) - PIC18C CAN Routines in ‘C’. 2001. Citado


na página 43.

RUFFINO, J. et al. Fault-tolerant broadcast in can. Munich, Germany, p. 150–159, 1998.


Citado na página 38.

SKYTRAQ Technology Inc. Venus638FLPx GPS Receiver Data Sheet. [S.l.], 2008. Citado
3 vezes nas páginas 13, 48 e 49.

SOUSA, R. de. CAN (Controller Area Network): uma abordagem para automação e
controle na área Agrícola. 83 p. Mestrado — Escola de Engenharia de São Carlos
Universidade de São Paulo, 2002. Citado 11 vezes nas páginas 11, 20, 26, 27, 28, 30, 33,
34, 35, 36 e 37.

SparkFun Electronics Inc. Venus GPS Logger with SMA Connector. 2002. Virtual.
Disponível em: www.sparkfun.com. Acessado em: 11/2014. Citado 3 vezes nas páginas 11,
48 e 51.

STRAUSS, C. Implementação e avaliação de uma rede experimental baseada em CAN


para aplicações agrícolas. 79 p. Mestrado — Escola Politécnica da Universidade de São
Paulo, 2001. Citado 2 vezes nas páginas 20 e 25.

SUZUKI, R. Desenvolvimento de Inerface Padrão ISO11783 para Adequação de Sensores


a Sistema de Automação para Implemento Agrícola. Graduação — Escola de Engenharia
de São Carlos Universidade de São Paulo, 2012. Citado 2 vezes nas páginas 11 e 19.

TANENBAUM, A. S. Redes de Computadores. 4. ed. [S.l.]: Editora Campus, 2003. 632 p.


Citado 2 vezes nas páginas 26 e 28.
Apêndices
63

APÊNDICE A – Código main ECU do PC


#include <xc.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "ECAN.h"
#include <plib/usart.h>
//-----------------------------------------------------------------------------
#pragma config OSC = HS
#pragma config PWRT = ON
#pragma config WDT = OFF, WDTPS = 1
#pragma config LVP = OFF
#pragma config DEBUG = OFF
#pragma config MCLRE = ON
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF,WRTB = OFF,
#pragma config WRTC = OFF,WRTD = OFF
#pragma config IESO = ON
//-----------------------------------------------------------------------------
// Definicoes
//-----------------------------------------------------------------------------
#define _XTAL_FREQ 20000000
#define BAUDRATE 57600
#define BRG_VAL ((_XTAL_FREQ/BAUDRATE)/16)-1
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//GPS Receiving and Parse Variables
//-----------------------------------------------------------------------------
/**
* @brief Registrador dos valores da IMU recebidos da CAN
*
* Definicao do tipo IMU_CAN
*
*/
typedefstruct IMU_CAN{
/**Campo para armazenar os valores do acelerometro*/
struct acel{
volatile int Ax;
volatile int Ay;
volatile int Az;
}acel;
/**Campo para armazenar os valores do acelerometro*/
struct giro{
volatile int Gx;
volatile int Gy;

volatile int Gz;


}giro;
/**Campo para armazenar os valores do acelerometro*/
struct mag{
volatile int Mx;
volatile int My;
volatile int Mz;
}mag;
}IMUCAN;

IMUCAN imuCan; //criar a variável IMU CAN com todos os valores da IMU
/**
* @brief Registrador dos valores do GPS recebidos da CAN
*
* Definicao do tipo GPS_CAN
*
*/
typedefstruct GPS_CAN{
/**Campo para armazenar os valores de UTC hora e tempo (minuto+segundos) em segundos*/
struct utc{
volatile double hour;
volatile double ts;
}utc;

/**Campo para armazenar os valores de posicao*/


struct pos{
volatile double lat;
volatile double lon;
}pos;
/**Campo para armazenar os valores de altitude e velocidade*/
struct mov{
volatile double alt;
volatile double spd;
}mov;
/**Campo para armazenar os valores de HDOP e Numero de Sat*/
struct aux{
volatile double hdop;
volatile int numSat;
}aux;
/**Campo para armazenar os valores de course*/
struct course{
volatile double course;
}course;

}GPSCAN;

GPSCAN gpsCan;

char mensagem[220];
int rxID[2];
int rxDataLength;
int cnt =0;
int flagGPSnew = 0;
int imuErr =0;
// Protótipo da Funções (Cabeçalho)
void ConfigPIC(void);
void InitializeUSART(void);
void interrupt Interrupcao() {

if (PIR1bits.RCIF) // check if receive interrupt has fired by USART


{

PIR1bits.RCIF = 0; // reset receive interrupt flag


}

if (INTCONbits.INT0IF)
{
INTCONbits.INT0IF = 0;
}

if (INTCONbits.TMR0IF == 1)
{
INTCONbits.TMR0IF = 0;
}

else if (INTCONbits.TMR0IF || INTCONbits.INT0IF)

{
INTCONbits.TMR0IF = 0; //Clear flag
INTCONbits.INT0IF = 0;

//...
}

}
//-----------------------------------------------------------------------------
void main() {

ConfigPIC();
InitializeUSART();
InitECAN();
while (1)
{
if(ECAN_Receive(&RxCANParse.dadosCAN,&rxID,rxDataLength))
{

if(rxID[1] == 0x40)// mensagem do GPS (0x40) com 3 dados em int


{
if(rxID[0] == 0x50) //utc (0x50)
{
gpsCan.utc.hour = RxCANParse.framed[0];
gpsCan.utc.ts = RxCANParse.framed[1];
}

if(rxID[0] == 0x51) //posicao (0x51)


{
gpsCan.pos.lat = RxCANParse.framed[0];
gpsCan.pos.lon = RxCANParse.framed[1];
flagGPSnew = 55;
}
if(rxID[0] == 0x52) //movimento (0x52)
{
gpsCan.mov.alt = RxCANParse.framed[0];
gpsCan.mov.spd = RxCANParse.framed[1];
}
if(rxID[0] == 0x53) //auxiliar (0x53)
{
gpsCan.aux.hdop = RxCANParse.framed[0];
gpsCan.aux.numSat = RxCANParse.framed[1];
}

if(rxID[0] == 0x54) //course (0x54)


{
gpsCan.course.course = RxCANParse.framed[0];
}

if(rxID[1] == 0x80)// mensagem da IMU (0x80) com 3 dados em int


{
if(rxID[0] == 0x60) //acelerometro (0x50)
{

PORTCbits.RC2 = !PORTCbits.RC2;
imuCan.acel.Ax = RxCANParse.framei[0];
imuCan.acel.Ay = RxCANParse.framei[1];
imuCan.acel.Az = RxCANParse.framei[2];
}

if(rxID[0] == 0x61) //giroscopio (0x51)


{
imuCan.giro.Gx = RxCANParse.framei[0];
imuCan.giro.Gy = RxCANParse.framei[1];
imuCan.giro.Gz = RxCANParse.framei[2];
}

if(rxID[0] == 0x62) //magnetometro (0x52)


{
imuCan.mag.Mx = RxCANParse.framei[0];
imuCan.mag.My = RxCANParse.framei[1];
imuCan.mag.Mz = RxCANParse.framei[2];
}

if(rxID[0] == 0x63) //magnetometro (0x52)


{
imuErr = RxCANParse.framei[0];

sprintf(mensagem,"$,Ax%d,Ay%d,Az%d,Gx%d,Gy%d,Gz%d,Mx%d,"
"My%d,Mz%d,Err%d,Hour%f,Ts%f,Lat%f,Lon%f,Spd%d,"
"HDOP%d,NSat%d,Cour%f,FGPS%d#",
imuCan.acel.Ax,imuCan.acel.Ay,imuCan.acel.Az,imuCan.giro.Gx,
imuCan.giro.Gy,imuCan.giro.Gz,imuCan.mag.Mx,imuCan.mag.My,
imuCan.mag.Mz,imuErr,gpsCan.utc.hour,gpsCan.utc.ts,
gpsCan.pos.lat,gpsCan.pos.lon,
gpsCan.mov.spd,gpsCan.aux.hdop,gpsCan.aux.numSat,
gpsCan.course.course,flagGPSnew);
putsUSART(mensagem);
if(flagGPSnew == 55)
flagGPSnew = 0;
}
}
}
}
}
}
//-----------------------------------------------------------------------------
void InitializeUSART(void) {

OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_ON &

USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, BRG_VAL);
}
//----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ConfigPIC(void) {
INTCONbits.GIEH = 1; // Habilita as interrupcoes de alta prioridade
INTCONbits.PEIE = 1; // enable peripheral interrupts.
INTCONbits.GIE = 1; // enable interrupts

OSCCONbits.IRCF = 0b111;
OSCTUNEbits.PLLEN = 0;

TRISCbits.RC2 = 0; //Saida medida de delay da rede


PORTCbits.RC2 = 0;

TRISCbits.RC3 = 0; //Saida medida de delay da rede


PORTCbits.RC3 = 0;

TRISCbits.RC6 = 0; //TX pin set as output


TRISCbits.RC7 = 1; //RX pin set as input
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
69

APÊNDICE B – Código main ECU da IMU


/*
* File: main.c
* Author: Daniel Diegues
* Descrição:
* TCC PIC 18F2580
*/

#include <xc.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "ECAN.h"
#include "imuclass.h"
#include <plib/usart.h>

//------------------------------------------------------------------------------
#pragma config OSC = HS
#pragma config PWRT = ON
#pragma config WDT = OFF, WDTPS = 1
#pragma config LVP = OFF
#pragma config DEBUG = OFF
#pragma config MCLRE = ON
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF,WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config IESO = ON

//------------------------------------------------------------------------------
// Definicoes
//------------------------------------------------------------------------------

#define _XTAL_FREQ 20000000


#define BAUDRATE 57900
#define BRG_VAL ((_XTAL_FREQ/BAUDRATE)/16)-1 // for high baud use 16 instaed 64

//------------------------------------------------------------------------------
//GPS Receiving and Parse Variables
//------------------------------------------------------------------------------

volatile unsigned char temp;


volatile unsigned char indexRx;
volatile unsigned char buffRx[70];

struct flag_Bits
{
int flagRxNew : 1;

int flagRxIni : 1;
int flagRxMat : 1;

}flagBits;

int cont = 0;

IMUregister imuReg;

void ConfigPIC(void);
void ConfigPIC(void);
void InitializeUSART(void);

void USART_putc(unsigned char c)


{
while (!TXSTAbits.TRMT); // wait until transmit shift register is empty
TXREG = c; // write character to TXREG and start transmission
}

void interrupt Interrupcao() {

if (PIR1bits.RCIF) // check if receive interrupt has fired by USART


{
temp = RCREG; // read received character to buffer

if(temp =='?')
flagBits.flagRxIni = 1; //controle da IMU

if(temp == '$')
{
flagBits.flagRxIni = 0; //controle da IMU (enviar 4)
flagBits.flagRxMat = 1; //controle de inicio de mensagem combinando
}

if( flagBits.flagRxMat)
flagBits.flagRxNew = getIMUmessage(temp,&imuReg);

if(flagBits.flagRxNew)
flagBits.flagRxMat = 0;

PIR1bits.RCIF = 0;
}
else if (INTCONbits.TMR0IF || INTCONbits.INT0IF)
{
INTCONbits.TMR0IF = 0; //Clear flag
INTCONbits.INT0IF = 0;
}

}
//------------------------------------------------------------------------------

void main()
{
ConfigPIC();
InitializeUSART();
InitECAN();
initIMU(&imuReg);

while (1)
{

if(flagBits.flagRxNew)
{

getIMUacel(&imuReg,&imuAcel);
getIMUgiro(&imuReg,&imuGiro);
getIMUmagn(&imuReg,&imuMagn);
imuECAN_Transmit(imuAcel.acel_x,imuAcel.acel_y,imuAcel.acel_z,8,0x60,0x80);
imuECAN_Transmit(imuGiro.giro_x,imuGiro.giro_y,imuGiro.giro_z,8,0x61,0x80);
imuECAN_Transmit(imuMagn.magn_x,imuMagn.magn_y,imuMagn.magn_z,8,0x62,0x80);
imuECAN_Transmit(COMSTAT,0,0,1,0x63,0x80);
flagBits.flagRxNew = 0;
}

if(flagBits.flagRxIni)
{
cont++;
if(cont > 0x1000)
{
USART_putc('4');
cont = 0;
}
}
}

void InitializeUSART(void) {

OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &

USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, BRG_VAL);

}
//----------------------------------------------------------------------------

void ConfigPIC(void) {

INTCONbits.GIEH = 1; // Habilita as interrupcoes de alta prioridade


INTCONbits.PEIE = 1; // enable peripheral interrupts.
INTCONbits.GIE = 1; // enable interrupts

OSCCONbits.IRCF = 0b111;
OSCTUNEbits.PLLEN = 0;

TRISB = 0x00;
TRISBbits.RB3 = 1;

// Initialize CAN module

TRISCbits.RC2 = 0;
PORTCbits.RC2 = 0;

TRISCbits.RC6 = 0; //TX pin set as output


TRISCbits.RC7 = 1; //RX pin set as input
flagBits.flagRxNew = 0;

}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
75

APÊNDICE C – Código main ECU da GPS


/*
* File: main.c
* Author: Daniel Diegues
* Descrição:
* TCC PIC 18F2580
*/
#include <xc.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "ECAN.h"
#include "gpsclass.h"
#include <plib/usart.h>

//------------------------------------------------------------------------------
#pragma config OSC = HS
#pragma config PWRT = ON
#pragma config WDT = OFF, WDTPS = 1
#pragma config LVP = OFF
#pragma config DEBUG = OFF
#pragma config MCLRE = ON
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF,WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config IESO = ON

//------------------------------------------------------------------------------
// Definicoes
//------------------------------------------------------------------------------

#define _XTAL_FREQ 20000000


#define BAUDRATE 9600
#define BRG_VAL ((_XTAL_FREQ/BAUDRATE)/64)-1

//------------------------------------------------------------------------------
//GPS Receiving and Parse Variables
//------------------------------------------------------------------------------

volatile unsigned char temp; //character RX

struct flag_Bits
{
int flagRxNew : 1;
int flagRxIni : 1;

}flagBits;

GPSregister gpsReg;
GPSutc gpsUTC;
GPSpos gpsPos;

GPSaux gpsAux;

GPScour gpsCour;

// Protótipo da Funções (Cabeçalho)


// Protótipo da Funções (Cabeçalho)

void ConfigPIC(void);

void InitializeUSART(void);

void interrupt Interrupcao() {

if (PIR1bits.RCIF) // check if receive interrupt has fired by USART


{
temp = RCREG; // read received character to buffer

if(temp == '$')
flagBits.flagRxIni = 1;

if(flagBits.flagRxIni)
flagBits.flagRxNew = getGPSmessage(temp,&gpsReg);

if(flagBits.flagRxNew)
flagBits.flagRxIni = 0;

PIR1bits.RCIF = 0; // reset receive interrupt flag


}

else if (INTCONbits.TMR0IF || INTCONbits.INT0IF)

{
INTCONbits.TMR0IF = 0; //Clear flag
INTCONbits.INT0IF = 0;
}

}
//------------------------------------------------------------------------------

void main() {

ConfigPIC();

initGPS(&gpsReg);
InitializeUSART();
InitECAN();

while (1)
{
if(flagBits.flagRxNew)
{
getGPSutc(&gpsReg,&gpsUTC,NULL);

getGPSpos(&gpsReg,&gpsPos,NULL);

getGPSaux(&gpsReg,&gpsAux,NULL);

getGPScour(&gpsReg,&gpsCour,NULL);

gpsECAN_Transmit(gpsUTC.utc_hour,gpsUTC.utc_ts,8,0x50,0x40);
gpsECAN_Transmit(gpsPos.pos_lat,gpsPos.pos_lon,8,0x51,0x40);
gpsECAN_Transmit(gpsPos.pos_lat,gpsPos.pos_lon,8,0x51,0x40);
gpsECAN_Transmit(gpsAux.aux_numsat,gpsAux.aux_numsat,8,0x53,0x40);
gpsECAN_Transmit(gpsCour.cour_cour,gpsCour.cour_cour,8,0x54,0x40);

flagBits.flagRxNew = 0;
}
}

void InitializeUSART(void) {

OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_LOW, BRG_VAL);

}
//----------------------------------------------------------------------------

void ConfigPIC(void) {

INTCONbits.GIEH = 1; // Habilita as interrupcoes de alta prioridade


INTCONbits.PEIE = 1; // enable peripheral interrupts.
INTCONbits.GIE = 1; // enable interrupts

OSCCONbits.IRCF = 0b111;
OSCTUNEbits.PLLEN = 0;

TRISB = 0x00;
TRISBbits.RB3 = 1;

// Initialize CAN module

TRISCbits.RC2 = 0;
PORTCbits.RC2 = 0;

TRISCbits.RC6 = 0; //TX pin set as output


TRISCbits.RC7 = 1; //RX pin set as input
flagBits.flagRxNew = 0;
}
//------------------------------------------------------------------------------
79

APÊNDICE D – Códigos biblioteca da IMU


/**
* @file gpsclass.h
* @brief Header da classe GPS para TCC
* @author Daniel Diegues
*
* @date 28 de Outubro de 2014
*/

/**
* @brief Registrador das mensagens da IMU com os campos de buffer temporarios
* para manter os dados sincronizados
*
* Definicao do tipo IMUregister
*
*/

typedefstruct reg_IMU{
/**Campo para armazenar a sentenca temporaria da IMU*/
volatile unsigned char bufferIMUTemp[50];
/**Campo para armazenar a sentenca completa da IMU*/
volatile unsigned char bufferIMU[50];
/**Campo para armazenar o index de cada um dos caracteres recebidos da
* serial*/
unsigned int index;

}IMUregister;

/**
* @brief Estrutura com os dados do Acelerometro (x,y,z)
* da funcao getIMUaccel
* Definicao do tipo IMUacel
*/
typedefstruct IMU_acel{
/**Campo para armazenar o valor do acelerometro em x*/
volatile int acel_x;
/**Campo para armazenar o valor do acelerometro em y*/
volatile int acel_y;
/**Campo para armazenar o valor do acelerometro em z*/
volatile int acel_z;

}IMUacel;

/**
* @brief Estrutura com os dados do Giroscopio (x,y,z)
* da funcao getIMUgiro
* Definicao do tipo IMUgiro

*/
typedefstruct IMU_giro{
typedefstruct IMU_giro{
/**Campo para armazenar o valor do giroscopio em x*/
volatile int giro_x;
/**Campo para armazenar o valor do giroscopio em y*/
volatile int giro_y;
/**Campo para armazenar o valor do giroscopio em z*/
volatile int giro_z;

}IMUgiro;

/**
* @brief Estrutura com os dados do Magnetometro (x,y,z)
* da funcao getIMUmagn
* Definicao do tipo IMUmagn
*/
typedefstruct IMU_magn{
/**Campo para armazenar o valor do magnetometro em x*/
volatile int magn_x;
/**Campo para armazenar o valor do magnetometro em y*/
volatile int magn_y;
/**Campo para armazenar o valor do magnetometro em z*/
volatile int magn_z;

}IMUmagn;

/*
* @brief Funcao de Inicializacao das variavies da IMU
*/
void initIMU(IMUregister *imuReg);
/*
* @brief Funcao que grava cada character no buffer.
* Grava em um buffer temporario
* Atualiza todo o buffer permanente ao fim da sentenca
*/
int getIMUmessage(char charRx,IMUregister *imuReg);

/*
* @brief Funcao para obter os dados do acelerometro
*/
int getIMUacel(IMUregister *imuReg,IMUacel *imuAcel);

/*
* @brief Funcao para obter os dados do acelerometro
*/

int getIMUgiro(IMUregister *imuReg,IMUgiro *imuGiro);

/*
* @brief Funcao para obter os dados do acelerometro
* @brief Funcao para obter os dados do acelerometro
*/
int getIMUmagn(IMUregister *imuReg,IMUmagn *imuMagn);

IMUregister imuReg;
IMUacel imuAcel;
IMUgiro imuGiro;
IMUmagn imuMagn;
#include <p18f2580.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xc.h>
#include "imuclass.h"
/**
*
* @param imuReg variavel do tipo IMUregister deve ser criada antes de utilizar a biblioteca
*/
void initIMU(IMUregister *imuReg)
{

imuReg->index = 0;
}

/**
* @brief Funcao que grava cada character no buffer.
* Grava no buffer temporario .
* Atualiza todo o buffer permanente ao mesmo instante ao fim da sentenca. (!! MUDAR O RETURN !!)
* @param charRx caracter recebido pela serial
* @param imuReg variavel do tipo IMUregister deve ser criada antes de utilizar a biblioteca
* contem o buffer da sentenca alem de controles internos
* @return retorna '1' a cada nova mensagem recebida e gravada no buffer correto cada vez que recebe '#'.
*/

int getIMUmessage(char charRx,IMUregister *imuReg)


{
if(charRx!='#') //not final of the message
{
imuReg->bufferIMUTemp[imuReg->index] = charRx; //save Rx data initial of string
imuReg->index++;
return 0;
}
else
{
imuReg->bufferIMUTemp[imuReg->index] = charRx; //put terminator in the end of message
strncpy(imuReg->bufferIMU, imuReg->bufferIMUTemp,(imuReg->index+1));//

imuReg->index = 0;
return 1;
}
}

/**
* @brief Funcao que extrai os dados do acelerometro.
* @param IMUReg variavel do tipo IMUregister os valores sao carregados pela funcao
* getIMUmessage
* @param imuAcel variavel do tipo IMUacel onde serao carregados os valores de saida da funcao
* @return 0 - success
* -1 - buffer vazio
*/
int getIMUacel(IMUregister *imuReg,IMUacel *imuAcel)
{
int i;
char temp_str[4];
char *sentence;

sentence = imuReg->bufferIMU;

for(i = 0;i < 2;i++)


{
if(sentence == NULL)
return -1;
if(i == 0)
{
temp_str[3] = 0;
strncpy(temp_str,sentence + 1,4);
imuAcel->acel_x = atoi(temp_str);
}

sentence = strchr(sentence, ',');// pointer to the separator ','


sentence++;//first character in field

//pull out data


if(i == 0)
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuAcel->acel_y = atoi(temp_str);
}
if(i == 1)
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuAcel->acel_z = atoi(temp_str);
return 0;
}
}

/**
* @brief Funcao que extrai os dados do giroscopio.
* @param IMUReg variavel do tipo IMUregister os valores sao carregados pela funcao
* getIMUmessage
* @param imuGiro variavel do tipo IMUgiro onde serao carregados os valores de saida da funcao
* @return 0 - success
* -1 - buffer vazio
*/
int getIMUgiro(IMUregister *imuReg,IMUgiro *imuGiro)
{
int i;
char temp_str[4];
char *sentence;

sentence = imuReg->bufferIMU;

for(i = 0;i < 5;i++)


{

if(sentence == NULL)
return -1;

sentence = strchr(sentence, ',');// pointer to the separator ','


sentence++;//first character in field

//pull out data


if(i == 2)
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuGiro->giro_x = atoi(temp_str);
}
if(i == 3)
if(i == 3)
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuGiro->giro_y = atoi(temp_str);
}
if(i == 4)
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //

imuGiro->giro_z = atoi(temp_str);
return 0;
}
}
}

/**
* @brief Funcao que extrai os dados do magnetometro.
* @param IMUReg variavel do tipo IMUregister os valores sao carregados pela funcao
* getIMUmessage
* @param imuMagn variavel do tipo IMUmagn onde serao carregados os valores de saida da funcao
* @return 0 - success
* -1 - buffer vazio
*/
int getIMUmagn(IMUregister *imuReg,IMUmagn *imuMagn)
{
int i;
char temp_str[4];
char *sentence;

sentence = imuReg->bufferIMU;

for(i = 0;i < 8;i++)


{

if(sentence == NULL)
return -1;

sentence = strchr(sentence, ',');// pointer to the separator ','


sentence++;//first character in field

//pull out data


if(i == 5)
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuMagn->magn_x = atoi(temp_str);
}
if(i == 6)
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuMagn->magn_y = atoi(temp_str);
}
if(i == 7)

{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuMagn->magn_z = atoi(temp_str);
return 0;
}
}
}
87

APÊNDICE E – Códigos biblioteca do GPS


/**
* @file gpsclass.h
* @brief Header da classe GPS para TCC
* @author Daniel Diegues
*
*/
/**
* @brief Registrador das mensagens NMEA do GPS com os campos de buffer temporarios
* para manter os dados sincronizados
*
* Definicao do tipo GPSregister
*
*/

typedefstruct reg_GPS{
/**Campo para armazenar os dados temporarios de GPGGA*/
volatile unsigned char bufferGGATemp[72];
/**Campo para armazenar os dados de temporarios GPGSA*/
volatile unsigned char bufferGSATemp[70];
/**Campo para armazenar os dados de temporarios GPGSV*/
volatile unsigned char bufferGSVTemp[70];
/**Campo para armazenar os dados de temporarios GPRMC*/
volatile unsigned char bufferRMCTemp[70];
/**Campo para armazenar os dados de temporarios GPVTG*/
volatile unsigned char bufferVTGTemp[70];
/**Campo para armazenar os dados de GPGGA*/
volatile unsigned char bufferGGA[72];
/**Campo para armazenar os dados de GPGSA*/
volatile unsigned char bufferGSA[70];
/**Campo para armazenar os dados de GPGSV*/
volatile unsigned char bufferGSV[70];
/**Campo para armazenar os dados de GPRMC*/
volatile unsigned char bufferRMC[70];
/**Campo para armazenar os dados de GPVTG*/
volatile unsigned char bufferVTG[70];
/**Campo para armazenar os dados incompletos temporarios durante o processo
* de leitura da serial. Nao deve ser considerado dado valido*/
volatile unsigned char bufferRxTemp[70];
/**Campo para armazenar o index de cada um dos caracteres recebidos da
* serial*/
unsigned int index;
/**Campo para indicar que recebeu uma mensagem de GPS inteira nova*/
}GPSregister;

/**
* @brief Estrutura com os dados UTC (hora, minuto, segundo e tempo em segundos)

* da funcao getUTC
* Definicao do tipo GPSutc
*/
typedefstruct GPS_utc{
/**Campo para armazenar a hora*/
/**Campo para armazenar a hora*/
volatile unsigned int utc_hour;
/**Campo para armazenar os minutos*/
volatile unsigned int utc_min;
/**Campo para armazenar os segundos (sem decimal)*/
volatile unsigned int utc_sec;
/**Campo para armazenar tempo em segundos com decimal e minutos convertidos*/
volatile double utc_ts;
}GPSutc;

/**
* @brief Estrutura com os dados de posicao
* Latitude, Longitude e altitude.
* da funcao getGPSpos
* Definicao do tipo GPSpos
*/
typedefstruct GPS_pos{
/**Campo para armazenar a latitude em graus*/
volatile double pos_lat;
/**Campo para armazenar a longitude em graus*/
volatile double pos_lon;
/**Campo para armazenar altitude em metros*/
volatile double pos_alt;

}GPSpos;

/**
* @brief Estrutura com os dados de mov
* Altitude e velocidade.
* da funcao getGPSmov
* Definicao do tipo GPSmov
*/
typedefstruct GPS_mov{
/**Campo para armazenar altitude*/
volatile double mov_alt;
/**Campo para armazenar velocidade*/
volatile double mov_spd;

}GPSmov;

/**
* @brief Estrutura com os dados de aux

* hdop e numSat.
* da funcao getGPSaux
* Definicao do tipo GPSaux
*/
typedefstruct GPS_aux{
/**Campo para armazenar altitude*/
volatile double aux_hdop;
/**Campo para armazenar velocidade*/
volatile double aux_numsat;
}GPSaux;

/**
* @brief Estrutura com os dados de cour
* course.
* da funcao getGPScour
* Definicao do tipo GPScour
*/
typedefstruct GPS_cour{
/**Campo para armazenar altitude*/
volatile double cour_cour;

}GPScour;

/*
* @brief Funcao de Inicializacao das variavies do GPS
*/
void initGPS(GPSregister *gpsReg);
/*
* @brief Funcao que grava cada character no buffer do padrao especifico.
* Grava em um buffer temporario
* Atualiza todos os buffers permanentes ao mesmo instante, quando recebe o GPVTG
*/
int getGPSmessage(char charRx,GPSregister *gpsReg);

/*
* @brief Funcao para obter os dados de tempo (UTC) do padrao solicitado
*/
int getGPSutc(GPSregister *gpsReg,GPSutc *gpsUTC,char std);

/*
* @brief Funcao para obter os dados de posicao.
* Sendo latitude, longitude e altitude.
*/

int getGPSpos(GPSregister *gpsReg,GPSpos *gpsPos,char std);

/*
* @brief Funcao para obter os dados de mov.
* Sendo latitude, longitude e altitude.
*/
int getGPSmov(GPSregister *gpsReg,GPSmov *gpsMov,char std);

/*
* @brief Funcao para obter os dados de aux.
* Sendo latitude, longitude e altitude.
*/
int getGPSaux(GPSregister *gpsReg,GPSaux *gpsAux,char std);
/*
* @brief Funcao para obter os dados de cour.
* Sendo latitude, longitude e altitude.
*/
int getGPScour(GPSregister *gpsReg,GPScour *gpsCour,char std);
#include <p18f2580.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xc.h>
#include "gpsclass.h"
/**
*
* @param gpsReg variavel do tipo GPSregister deve ser criada antes de utilizar a biblioteca
*/
void initGPS(GPSregister *gpsReg)
{
gpsReg->index = 0;
}

/**
* @brief Funcao que grava cada character no buffer do padrao especifico.
* Grava em um buffer temporario .
* Atualiza todos os buffers permanentes ao mesmo instante, quando recebe o GPVTG.
* @param charRx caracter recebido pela serial
* @param gpsReg variavel do tipo GPSregister deve ser criada antes de utilizar a biblioteca
* contem os buffers com os padroes GGA, GSA, GSV, RMC e VTG alem de controles internos
* @return retorna '1' a cada nova mensagem recebida e gravada no buffer correto cada vez que recebe '*'.
*/

int getGPSmessage(char charRx,GPSregister *gpsReg)


{
if(charRx!='*') //not final of the message
{
gpsReg->bufferRxTemp[gpsReg->index] = charRx; //save Rx data initial of string
gpsReg->index++;
return 0;
}
else
{
gpsReg->bufferRxTemp[gpsReg->index] = charRx; //put terminator in the end of message

if(!strncmp(gpsReg->bufferRxTemp,"$GPGGA",6))
strncpy(gpsReg->bufferGGATemp, gpsReg->bufferRxTemp,(gpsReg->index+1));

if(!strncmp(gpsReg->bufferRxTemp,"$GPGSA",6))
strncpy(gpsReg->bufferGSATemp, gpsReg->bufferRxTemp,(gpsReg->index+1));

if(!strncmp(gpsReg->bufferRxTemp,"$GPGSV",6))

strncpy(gpsReg->bufferGSVTemp, gpsReg->bufferRxTemp,(gpsReg->index+1));

if(!strncmp(gpsReg->bufferRxTemp,"$GPRMC",6))
strncpy(gpsReg->bufferRMCTemp, gpsReg->bufferRxTemp,(gpsReg->index+1));

if(!strncmp(gpsReg->bufferRxTemp,"$GPVTG",6))
{
strncpy(gpsReg->bufferVTG, gpsReg->bufferRxTemp,(gpsReg->index+1));
strncpy(gpsReg->bufferGGA, gpsReg->bufferGGATemp,72);
strncpy(gpsReg->bufferGSA, gpsReg->bufferGSATemp,70);
strncpy(gpsReg->bufferGSV, gpsReg->bufferGSVTemp,70);
strncpy(gpsReg->bufferRMC, gpsReg->bufferRMCTemp,70);
}
gpsReg->index = 0;
return 1;

}
}
/**
* @brief Funcao que extrai os dados de tempo (UTC) do padrao solicitado.
* @param gpsReg variavel do tipo GPSregister os valores sao carregados pela funcao
* getGPSmessage
* @param gpsUTC variavel do tipo GPSutc onde serao carregados os valores de saida da funcao
* @param std parametro com padrao de sentenca de onde deseja ser extraido o UTC
* (!! Atualmente so o GGA !!)
* @return 0 - success
* -1 - parsing error
* -2 - sentence marked invalid
*/
int getGPSutc(GPSregister *gpsReg,GPSutc *gpsUTC,char std)
{
int i;
char temp_str[3];
char *sentence;

sentence = gpsReg->bufferGGA;
if(strncmp(sentence,"$GPGGA", 6) == 0)
{

for(i = 0;i < 1;i++)


{
sentence = strchr(sentence, ',');// pointer to the separator ','
if(sentence == NULL)
return -1;
sentence++;//first character in field

//pull out data


if(i == 0) //UTC
{
temp_str[2] = 0;
strncpy(temp_str, sentence, 2); // hour
gpsUTC->utc_hour = atoi(temp_str);

strncpy(temp_str, sentence + 2, 2);//minutes


gpsUTC->utc_min = atoi(temp_str);

strncpy(temp_str, sentence + 4, 2);//seconds


gpsUTC->utc_sec = atoi(temp_str);

temp_str[5] = 0;
strncpy(temp_str, sentence + 4, 6);//seconds and decimal
gpsUTC->utc_ts = ((gpsUTC->utc_min)*60) + atof(temp_str);//
return 0;
}
}
}
else
return -2;
}
/**
* @brief Funcao de auxilio para converter a latitude e longitude em graus
* @param coord entrada de dados da coordenada para ser convertida
* @param degrees saida de dados com a coordenada convertida em graus
* @return 0 - success
* -1 - parsing error
* -2 - sentence marked invalid
*/

int GPStodegree(char *coord, double *degrees)


{
char *decimal_point;
char temp[2];
char temp[2];
char dummy[2];
double tempdegrees = 0;
decimal_point = strchr(coord, '.');

if(decimal_point == NULL)
return -1;

temp[2] = 0;

strncpy(temp, decimal_point - 4, 2);


*degrees = atof(temp)*10;
strncpy(temp, decimal_point - 2, 2);
*degrees += atof(temp)/6;
strncpy(temp, decimal_point + 1, 4);
tempdegrees = atof(temp)/100;
*degrees += tempdegrees/600;
return 0;
}

/**
* @brief Funcao que extrai os dados de posicao Latitude e Longitude em Graus
* e Altitude em metros.
* @param gpsReg variavel do tipo GPSregister os valores sao carregados pela funcao
* getGPSmessage
* @param gpsPos variavel do tipo GPSpos onde serao carregados os valores de saida da funcao
* @param std parametro com padrao de sentenca de onde deseja extrair a Pos
* (!! Atualmente so o GGA !!)
* @return 0 - success
* -1 - parsing error
* -2 - sentence marked invalid
*/
int getGPSpos(GPSregister *gpsReg,GPSpos *gpsPos,char std)
{
int i;
char temp_str[3];
char *sentence;

sentence = gpsReg->bufferGGA;
if(strncmp(sentence,"$GPGGA", 6) == 0)
{

for(i = 0; i < 11; i++)


{
sentence = strchr(sentence, ',');// pointer to the separator ','
if(sentence == NULL)
return -1;
sentence++;//first character in field

//pull out data


if(i == 1) //latitude
{
if(GPStodegree(sentence,&gpsPos->pos_lat))
return -1;

}
if(i == 2) //latitude direction
{
if(*sentence == 'S')
gpsPos->pos_lat = -gpsPos->pos_lat;
}
if(i == 3) //longitude
{
if(GPStodegree(sentence,&gpsPos->pos_lon))
if(GPStodegree(sentence,&gpsPos->pos_lon))
return -1;
}
if(i == 4) //longitude
{
if(*sentence == 'W')
gpsPos->pos_lon = -gpsPos->pos_lon;
}
}
}
else
return -2;
}

/**
* @brief Funcao que extrai os dados de posicao altitude e velocidade
* e Altitude em metros.
* @param gpsReg variavel do tipo GPSregister os valores sao carregados pela funcao
* getGPSmessage
* @param gpsSatCur variavel do tipo GPSpos onde serao carregados os valores de saida da funcao
* @param std parametro com padrao de sentenca de onde deseja extrair a Pos
* (!! Atualmente so o GGA !!)
* @return 0 - success
* -1 - parsing error
* -2 - sentence marked invalid
*/

int getGPSmov(GPSregister *gpsReg,GPSmov *gpsMov,char std)


{

return -2;
}

int getGPSaux(GPSregister *gpsReg,GPSaux *gpsAux,char std)


{
int i;
char temp_str[3];

char *sentence;

sentence = gpsReg->bufferGGA;
if(strncmp(sentence,"$GPGGA", 6) == 0)
{

for(i = 0; i < 11; i++)


{
sentence = strchr(sentence, ',');// pointer to the separator ','
if(sentence == NULL)
return -1;
sentence++;//first character in field

//pull out data


if(i == 6) //numSat
{
temp_str[2] = 0;
strncpy(temp_str, sentence, 2); // num satelites
gpsAux->aux_numsat = atof(temp_str);
return -1;
}
if(i == 7) //hdop
{
}
}
}
else
else
return -2;
}

int getGPScour(GPSregister *gpsReg,GPScour *gpsCour,char std)


{
int i;
char temp_str[3];
char *sentence;

sentence = gpsReg->bufferVTG;
if(strncmp(sentence,"$GPVTG", 6) == 0)
{

for(i = 0; i < 5; i++)


{
sentence = strchr(sentence, ',');// pointer to the separator ','
if(sentence == NULL)
return -1;
sentence++;//first character in field

//pull out data


if(i == 0) //course
{
temp_str[2] = 0;
strncpy(temp_str, sentence, 5); // course
gpsCour->cour_cour = atof(temp_str);
return -1;
}
}
}
else
return -2;
}
97

APÊNDICE F – Códigos biblioteca ECAN


/**
* @file ECAN.h
* @brief Header da classe Extended CAN
* @author Daniel Diegues
*/

#ifndef _ECAN_H
#define _ECAN_H

#define TRUE 1
#define FALSE 0

/*Campos*/
union parse_CANTX
{
int framei[3];
double framed[2];
unsigned char dadosCAN[8];

}TxCANParse;

union parse_CANRX
{
double framed[2];
int framei[3];
unsigned char dadosCAN[8];

}RxCANParse;

void InitECAN(void);

unsigned char ECAN_Receive(unsigned char *data,int *ptRxID, int RxDLC);


void gpsECAN_Transmit(double data0, double data1, int dLc, int sIDh0, int sIDl0 );
void imuECAN_Transmit(int data0,int data1,int data2, int dLc, int sIDh0, int sIDl0);

#endif
#include <p18f2580.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xc.h>
#include "ECAN.h"

unsigned char temp_EIDH;


unsigned char temp_EIDL;
unsigned char temp_SIDH;
unsigned char temp_SIDL;
unsigned char temp_DLC;
unsigned char temp_D0;
unsigned char temp_D1;
unsigned char temp_D2;
unsigned char temp_D3;
unsigned char temp_D4;
unsigned char temp_D5;
unsigned char temp_D6;
unsigned char temp_D7;

void InitECAN(void)
{
CANCON = 0x00;

CANCON = 0x80;
while(!((CANSTATbits.OPMODE0==0) && (CANSTATbits.OPMODE1==0) && (CANSTATbits.OPMODE2==1)));

ECANCONbits.MDSEL0 = 0x00;
ECANCONbits.MDSEL1 = 0x00;

BRGCON1 = 0x81;
BRGCON2 = 0x90;
BRGCON3 = 0x00;

// Initialize Receive Masks


RXM0EIDH = 0x00;
RXM0EIDL = 0x00;
RXM0SIDH = 0xFF;
RXM0SIDL = 0xE0;

RXM1EIDH = 0x00;

RXM1EIDL = 0x00;
RXM1SIDH = 0xFF;
RXM1SIDL = 0xE0;

RXFCON0 = 0x00; //Disable all


RXFCON1 = 0x00; //Disable all

RXF0EIDH = 0x00;
RXF0EIDL = 0x00;
RXF0SIDH = 0x32;
RXF0SIDL = 0xC0;

RXF2EIDH = 0x00;
RXF2EIDH = 0x00;
RXF2EIDL = 0x00;
RXF2SIDH = 0x33;
RXF2SIDL = 0xC0;

CANCONbits.REQOP0 = 0;
CANCONbits.REQOP1 = 0;
CANCONbits.REQOP2 = 0;

while(!((CANSTATbits.OPMODE0==0) && (CANSTATbits.OPMODE1==0) && (CANSTATbits.OPMODE2==0) ) );

RXB0CON = 0x00;
RXB1CON = 0x00;

}
unsigned char ECAN_Receive(unsigned char *data,int *ptRxID, int RxDLC)
{

unsigned char RXMsgFlag;

RXMsgFlag = 0x00;

if (RXB0CONbits.RXFUL) //CheckRXB0
{

temp_EIDH = RXB0EIDH;
temp_EIDL = RXB0EIDL;
temp_SIDH = RXB0SIDH;
ptRxID[0] = RXB0SIDH;

temp_SIDL = RXB0SIDL;
ptRxID[1] = RXB0SIDL;
temp_DLC = RXB0DLC;
RxDLC = RXB0DLC;
temp_D0 = RXB0D0;

data[0] = RXB0D0;
temp_D1 = RXB0D1;
data[1] = RXB0D1;
temp_D2 = RXB0D2;
data[2] = RXB0D2;
temp_D3 = RXB0D3;
data[3] = RXB0D3;
temp_D4 = RXB0D4;
data[4] = RXB0D4;
temp_D5 = RXB0D5;
data[5] = RXB0D5;
temp_D6 = RXB0D6;
data[6] = RXB0D6;
temp_D7 = RXB0D7;
data[7] = RXB0D7;

RXB0D0 = 0;
RXB0D1 = 0;
RXB0D2 = 0;
RXB0D3 = 0;
RXB0D4 = 0;
RXB0D4 = 0;
RXB0D5 = 0;
RXB0D6 = 0;
RXB0D7 = 0;

RXB0CONbits.RXFUL = 0;
RXMsgFlag = 0x01;
}
else if (RXB1CONbits.RXFUL) //CheckRXB1
{
temp_EIDH = RXB1EIDH;
temp_EIDL = RXB1EIDL;
temp_SIDH = RXB1SIDH;
temp_SIDL = RXB1SIDL;
temp_DLC = RXB1DLC;
temp_D0 = RXB1D0;
temp_D1 = RXB1D1;
temp_D2 = RXB1D2;
temp_D3 = RXB1D3;

temp_D4 = RXB1D4;
temp_D5 = RXB1D5;
temp_D6 = RXB1D6;
temp_D7 = RXB1D7;
RXB1CONbits.RXFUL = 0;
RXMsgFlag = 0x01;
}
else if (B0CONbits.RXFUL) //CheckB0
{
temp_EIDH = B0EIDH;
temp_EIDL = B0EIDL;
temp_SIDH = B0SIDH;
temp_SIDL = B0SIDL;
temp_DLC = B0DLC;
temp_D0 = B0D0;
temp_D1 = B0D1;
temp_D2 = B0D2;
temp_D3 = B0D3;
temp_D4 = B0D4;
temp_D5 = B0D5;
temp_D6 = B0D6;
temp_D7 = B0D7;

B0CONbits.RXFUL = 0;
RXMsgFlag = 0x01;
}

if (RXMsgFlag == 0x01)
{
RXMsgFlag = 0x00;
PIR3bits.RXB1IF = 0; //A CAN Receive Buffer has received a new message
return TRUE;
}
else
{
return FALSE;
}
}
}

void gpsECAN_Transmit(double data0, double data1, int dLc, int sIDh0, int sIDl0 )
{
TxCANParse.framed[0] = data0;
TxCANParse.framed[1] = data1;

TXB0EIDH = 0x00;
TXB0EIDL = 0x00;

TXB0SIDH = sIDh0;
TXB0SIDL = sIDl0;

TXB0DLC = dLc;

TXB0D0 = TxCANParse.dadosCAN[0];
TXB0D1 = TxCANParse.dadosCAN[1];
TXB0D2 = TxCANParse.dadosCAN[2];
TXB0D3 = TxCANParse.dadosCAN[3];
TXB0D4 = TxCANParse.dadosCAN[4];
TXB0D5 = TxCANParse.dadosCAN[5];
TXB0D6 = TxCANParse.dadosCAN[6];
TXB0D7 = TxCANParse.dadosCAN[7];

TXB0CONbits.TXREQ = 1; //Set the buffer to transmit

while(TXB0CONbits.TXREQ);

void imuECAN_Transmit(int data0,int data1,int data2, int dLc, int sIDh0, int sIDl0 )
{
TxCANParse.framei[0] = data0;
TxCANParse.framei[1] = data1;
TxCANParse.framei[2] = data2;

TXB0EIDH = 0x00;
TXB0EIDL = 0x00;

TXB0SIDH = sIDh0;
TXB0SIDL = sIDl0;

TXB0DLC = dLc;

TXB0D0 = TxCANParse.dadosCAN[0];
TXB0D1 = TxCANParse.dadosCAN[1];
TXB0D2 = TxCANParse.dadosCAN[2];
TXB0D3 = TxCANParse.dadosCAN[3];
TXB0D4 = TxCANParse.dadosCAN[4];
TXB0D5 = TxCANParse.dadosCAN[5];
TXB0D6 = TxCANParse.dadosCAN[6];
TXB0D7 = TxCANParse.dadosCAN[7];

TXB0CONbits.TXREQ = 1; //Set the buffer to transmit

while(TXB0CONbits.TXREQ);

Vous aimerez peut-être aussi