Beruflich Dokumente
Kultur Dokumente
São Carlos
2014
Daniel Diegues
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.
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
ACK Acknowledge
1 INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
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
6 CONSIDERAÇÕES FINAIS . . . . . . . . . . . . . . . . . . . . . . . 57
6.1 Trabalhos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.2 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Referências . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
APÊNDICES 61
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)
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
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
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).
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).
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).
• 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.
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.
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).
Para tanto, o tempo de bit é dividido quatro seguimentos (Bosch Gmbh, 1991; Di
Natale et al., 2012):
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:
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).
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.
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
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
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).
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.
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:
• 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;
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:
• Velocidade;
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).
Cada linha na Tabela 3 representa uma mensagem que será disponibilizada na rede,
analisando essa tabela temos as seguinte informações:
• 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;
• 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).
– 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.
Figura 18 – Placa receptor de GPS. Retirado de: SparkFun Electronics Inc. (2002).
• $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
# 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
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.
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:
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
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
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.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
NXP Semiconductors. Level Shifting Techniques in I2C-bus Design. 2007. Citado 4 vezes
nas páginas 11, 44, 47 e 48.
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.
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;
}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 (INTCONbits.INT0IF)
{
INTCONbits.INT0IF = 0;
}
if (INTCONbits.TMR0IF == 1)
{
INTCONbits.TMR0IF = 0;
}
{
INTCONbits.TMR0IF = 0; //Clear flag
INTCONbits.INT0IF = 0;
//...
}
}
//-----------------------------------------------------------------------------
void main() {
ConfigPIC();
InitializeUSART();
InitECAN();
while (1)
{
if(ECAN_Receive(&RxCANParse.dadosCAN,&rxID,rxDataLength))
{
PORTCbits.RC2 = !PORTCbits.RC2;
imuCan.acel.Ax = RxCANParse.framei[0];
imuCan.acel.Ay = RxCANParse.framei[1];
imuCan.acel.Az = RxCANParse.framei[2];
}
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;
#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
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//GPS Receiving and Parse Variables
//------------------------------------------------------------------------------
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);
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) {
OSCCONbits.IRCF = 0b111;
OSCTUNEbits.PLLEN = 0;
TRISB = 0x00;
TRISBbits.RB3 = 1;
TRISCbits.RC2 = 0;
PORTCbits.RC2 = 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
75
//------------------------------------------------------------------------------
#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
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//GPS Receiving and Parse Variables
//------------------------------------------------------------------------------
struct flag_Bits
{
int flagRxNew : 1;
int flagRxIni : 1;
}flagBits;
GPSregister gpsReg;
GPSutc gpsUTC;
GPSpos gpsPos;
GPSaux gpsAux;
GPScour gpsCour;
void ConfigPIC(void);
void InitializeUSART(void);
if(temp == '$')
flagBits.flagRxIni = 1;
if(flagBits.flagRxIni)
flagBits.flagRxNew = getGPSmessage(temp,&gpsReg);
if(flagBits.flagRxNew)
flagBits.flagRxIni = 0;
{
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) {
OSCCONbits.IRCF = 0b111;
OSCTUNEbits.PLLEN = 0;
TRISB = 0x00;
TRISBbits.RB3 = 1;
TRISCbits.RC2 = 0;
PORTCbits.RC2 = 0;
/**
* @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
*/
/*
* @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 '#'.
*/
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;
/**
* @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;
if(sentence == NULL)
return -1;
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;
if(sentence == NULL)
return -1;
{
temp_str[3] = 0;
strncpy(temp_str, sentence, 4); //
imuMagn->magn_z = atoi(temp_str);
return 0;
}
}
}
87
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.
*/
/*
* @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 '*'.
*/
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)
{
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
*/
if(decimal_point == NULL)
return -1;
temp[2] = 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)
{
}
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
*/
return -2;
}
char *sentence;
sentence = gpsReg->bufferGGA;
if(strncmp(sentence,"$GPGGA", 6) == 0)
{
sentence = gpsReg->bufferVTG;
if(strncmp(sentence,"$GPVTG", 6) == 0)
{
#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);
#endif
#include <p18f2580.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xc.h>
#include "ECAN.h"
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;
RXM1EIDH = 0x00;
RXM1EIDL = 0x00;
RXM1SIDH = 0xFF;
RXM1SIDL = 0xE0;
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;
RXB0CON = 0x00;
RXB1CON = 0x00;
}
unsigned char ECAN_Receive(unsigned char *data,int *ptRxID, int RxDLC)
{
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];
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];
while(TXB0CONbits.TXREQ);