Rede CAN para Estimativa de Orientação e Posição de Máquinas
Transcrição
Rede CAN para Estimativa de Orientação e Posição de Máquinas
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) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figura 2 – Representação de uma arquitetura centralizada . . . . . . . . . . . . . Figura 3 – Representação de uma arquitetura distribuída . . . . . . . . . . . . . . Figura 4 – Camadas da rede CAN. Adaptado de: Bosch Gmbh (1991). . . . . . . . Figura 5 – Níveis dos Sinais Elétricos ISO 11898-2. Retirado de: Di Natale et al. (2012) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figura 6 – Tempo de bit nominal. Adaptado de: Di Natale et al. (2012) . . . . . . Figura 7 – Quadro de dados Fonte: Sousa (2002). . . . . . . . . . . . . . . . . . . Figura 8 – Quadro remoto CAN 2.0b. Retirado de: Sousa (2002). . . . . . . . . . . Figura 9 – Estados de erros possíveis. Retirado de: Sousa (2002). . . . . . . . . . . Figura 10 – Exemplo do processo de arbitragem. Retirado de: Di Natale et al. (2012). Figura 11 – Ilustração do conceito de multicast. Retirado de: CiA (2002). . . . . . . Figura 12 – Máscara e filtro para mensagem CAN. Adaptado de: Di Natale et al. (2012). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figura 13 – Topologia do protótipo da rede de testes. . . . . . . . . . . . . . . . . . Figura 14 – Topologias de ECU. . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figura 15 – Esquemático do circuito utilizado para as ECUs. . . . . . . . . . . . . Figura 16 – Placa do circuito utilizado para as ECUs. . . . . . . . . . . . . . . . . Figura 17 – Circuito do conversor de nível bidirecional. Retirado de: NXP Semiconductors (2007). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figura 18 – Placa receptor de GPS. Retirado de: SparkFun Electronics Inc. (2002). Figura 19 – Esquemático da união na memória. . . . . . . . . . . . . . . . . . . . . Figura 20 – Placa da IMU. Retirado de: SparkFun Electronics Inc. (2002). . . . . . Figura 21 – Fluxograma da função principal da IMU. . . . . . . . . . . . . . . . . . Figura 22 – Sinais CAN L e CAN H obtidos da rede implementada. . . . . . . . . . Figura 23 – Medida de atraso da rede de testes. . . . . . . . . . . . . . . . . . . . . 19 24 24 27 31 31 33 34 35 36 37 38 42 43 45 46 48 48 51 51 52 55 56 Lista de tabelas Tabela 1 – Características físicas da norma SAE J1939. Adaptado de: Di Natale et al. (2012). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tabela 3 – Dicionário de dados da rede. . . . . . . . . . . . . . . . . . . . . . . . Tabela 4 – Descrição dos campos da mensagem NMEA 0183 GPGGA. Modificado de: SKYTRAQ Technology Inc. (2008). . . . . . . . . . . . . . . . . . Tabela 5 – Descrição dos campos da mensagem NMEA 0183 GPVTG. Modificado de: SKYTRAQ Technology Inc. (2008). . . . . . . . . . . . . . . . . . . 29 . 30 . 42 . 49 . 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 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 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 5.3 Atraso nos dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 6 6.1 6.2 CONSIDERAÇÕES FINAIS . . . . . . . . . . . . . . . . . . . . . . . 57 Trabalhos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 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 variabilidades 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, seguranç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 posicionamento 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 conceitos 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, possibilitado 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 determinados 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 barramento 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 automá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 Barramento Arbitragem de acesso a rede Velocidade Máximo de nós Topologia Comprimento do tronco Comprimento da derivação Terminação Cabo Conector Definição Par Diferencial Aleatório, não destrutivo, bit dominante 250kbps 30 Barramento linear 40m 1m 2 Par trançado blindado ligado ao terra 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 1Mb/s 800kb/s 500kb/s 250kb/s 125kb/s 62.5kb/s 20kb/s 10kb/s Comprimento[m] 30 50 100 250 500 1000 2500 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 representados 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 sincronizaçã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 transmissã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 comunicaçã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 Universal 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. # Descrição da Mensagem Repetição 1 1 2 3 4 5 6 7 UTC Posição - Latitude e Longitude Velocidade e Altitude # Satélites Curso Acelerômetro (Ax,Ay,Az) Giroscópio (Gx,Gy,Gz) Magnetômetro (Mx,My,Mz) 1Hz 1Hz 1Hz 1Hz 1Hz 17Hz 17Hz 17Hz ECU GPS TX TX TX TX TX - ECU IMU TX TX TX ECU PC RX RX RX RX RX RX RX RX ID0 ID1 0x50 0x51 0x52 0x53 0x54 0x60 0x61 0x62 0x40 0x40 0x40 0x40 0x40 0x80 0x80 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 R PIC 18F2580 da Microchip , o código embarcado foi desenvolvido na linguagem C R utilizando o compilador XC8 e o ambiente de desenvolvimento MPLABX , 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 microcontrolador 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 desenvolvimento 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 sinais 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 R O dispositivo MCP2551 MICROCHIP é 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). # 1 2 3 4 5 6 7 8 9 10 11 Descrição Tempo UTC Latitude Indicador Norte/Sul Longitude Indicador Leste/Oeste Qualidade do GPS (modos) Satélites Utilizados HDOP Altitude acima do mar Estação DGPS Checksum Formato hhmmss.sss ddmm.mmmm N/S dddmm.mmmm E/W 0-8 00-12 00.0-99.9 mmm.c ID, distancias 02 Tabela 5 – Descrição dos campos da mensagem NMEA 0183 GPVTG. Modificado de: SKYTRAQ Technology Inc. (2008). # 1 2 3 4 5 Descrição Curso (graus) Velocidade do chão (nós) Velocidade do chão (km/h) Modo de Operação Checksum Formato 000.0 - 359.9 000.0 - 999.9 0000.0 - 1800.0 carácter 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 magnetô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 nova? N IMU em Reset? S Separa os dados da mensagem getIMUacel N S Envia Configuração da IMU Envia os dados na CAN ECAN_Transmit 1 2 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 R no software MatLab . 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 desenvolvida é 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 protocolo 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) { PIR1bits.RCIF = 0; // check if receive interrupt has fired by USART // 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) { imuCan.mag.Mx = imuCan.mag.My = imuCan.mag.Mz = } //magnetometro (0x52) RxCANParse.framei[0]; RxCANParse.framei[1]; 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 #include #include #include <stdio.h> <stdarg.h> <stdlib.h> <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 #pragma #pragma #pragma config config config config LVP = OFF DEBUG = OFF MCLRE = ON 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) { temp = RCREG; // check if receive interrupt has fired by USART // 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 #include #include #include <stdarg.h> <stdlib.h> <string.h> "ECAN.h" #include "gpsclass.h" #include <plib/usart.h> //-----------------------------------------------------------------------------#pragma #pragma #pragma #pragma config config config config OSC PWRT WDT LVP = = = = HS ON OFF, WDTPS = 1 OFF #pragma #pragma #pragma #pragma config config config config DEBUG = OFF MCLRE = ON CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF,CPB = OFF,CPD = OFF 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; 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) //character RX // 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. * @param charRx caracter recebido pela serial (!! MUDAR O RETURN !!) * @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 #define FALSE 1 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 #include #include #include #include <stdio.h> <stdlib.h> <string.h> <xc.h> "ECAN.h" unsigned char temp_EIDH; unsigned char temp_EIDL; unsigned char temp_SIDH; unsigned unsigned unsigned unsigned unsigned char char char char char temp_SIDL; temp_DLC; temp_D0; temp_D1; temp_D2; unsigned unsigned unsigned unsigned unsigned char char char char char temp_D3; temp_D4; temp_D5; temp_D6; 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; RXFCON1 = 0x00; RXF0EIDH = 0x00; RXF0EIDL = 0x00; RXF0SIDH = 0x32; RXF0SIDL = 0xC0; RXF2EIDH = 0x00; //Disable all //Disable all 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 temp_EIDL temp_SIDH ptRxID[0] = = = = RXB0EIDH; RXB0EIDL; RXB0SIDH; 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 data[2] temp_D3 data[3] temp_D4 = = = = = RXB0D2; RXB0D2; RXB0D3; RXB0D3; RXB0D4; data[4] temp_D5 data[5] temp_D6 data[6] = = = = = RXB0D4; RXB0D5; RXB0D5; RXB0D6; RXB0D6; temp_D7 = RXB0D7; data[7] = RXB0D7; RXB0D0 = 0; RXB0D1 = 0; RXB0D2 = 0; RXB0D3 = 0; RXB0D4 = 0; RXB0D4 RXB0D5 RXB0D6 RXB0D7 = = = = 0; 0; 0; 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 temp_EIDL temp_SIDH temp_SIDL = = = = B0EIDH; B0EIDL; B0SIDH; B0SIDL; temp_DLC = B0DLC; temp_D0 = B0D0; temp_D1 = B0D1; temp_D2 = B0D2; temp_D3 = B0D3; temp_D4 temp_D5 temp_D6 temp_D7 = = = = B0D4; B0D5; B0D6; 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 TXB0D1 TXB0D2 TXB0D3 = = = = TxCANParse.dadosCAN[0]; TxCANParse.dadosCAN[1]; TxCANParse.dadosCAN[2]; TxCANParse.dadosCAN[3]; TXB0D4 TXB0D5 TXB0D6 TXB0D7 = = = = TxCANParse.dadosCAN[4]; TxCANParse.dadosCAN[5]; TxCANParse.dadosCAN[6]; 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 TXB0D1 TXB0D2 TXB0D3 TXB0D4 = = = = = TxCANParse.dadosCAN[0]; TxCANParse.dadosCAN[1]; TxCANParse.dadosCAN[2]; TxCANParse.dadosCAN[3]; 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); }