
O próprio barramento CAN já é muito utilizado, onde estou interessado em seu uso no carro, embora essa área não possa ser limitada. Especialmente há alguns anos, essa oportunidade apareceu. Eu olhei para as especificações gerais - parece não haver nada de particularmente complicado. Eu olhei para os programas encontrados na Internet - e eu não gostava de um, cada um deles carecia de algo que parecia necessário para mim naquele momento. Vou reinventar minha bicicleta. Faço meu CAN farejar ainda mais sob o corte.
Barramento CAN
A descrição detalhada dos detalhes técnicos do barramento CAN faz parte da documentação. Neste artigo, basta saber que:
- possui uma conexão física de dois fios
- existem várias taxas de dados
- chips prontos e até placas prontas com peças soldadas já estão disponíveis para conexão
Depois de folhear as páginas de uma famosa loja online do Reino Médio, pedi várias opções diferentes de escudos e fui estudar as características dos sinais elétricos em um carro. O carro experimental foi o LADA Kalina Cross com o 127º motor e uma unidade de controle eletrônico ITELMA M74.5 CAN.
Eu conecto o conector de diagnóstico OBD (pinos 6 e 14) e olho o osciloscópio que está lá. Depois de girar a chave de ignição, pacotes com uma amplitude de até 2,5 V. Começo a fazer uma pausa no osciloscópio e olho para o pacote.
Os bits de início e parada são perceptíveis, alguns dados no pacote. Naquela época, eu já sabia que a taxa de transferência de dados era de 500 kbit / s, como a mais frequente para o barramento CAN do motor. A duração do pacote é de cerca de 230 μs e antes do pacote há uma pausa bastante grande na transmissão de dados. Escalo o tempo e vejo três pacotes e pausas entre eles.
Se adicionarmos a duração da transferência de dados e a pausa entre pacotes, acontece que a transferência de um dado leva cerca de 1 ms.
Por que estou deduzindo tudo isso? E a pergunta é puramente prática: existe velocidade de porta serial suficiente para transferir todos os dados? E com base no que vimos, podemos concluir que a velocidade de 500 kbit / s se desenvolve dentro do pacote, o que leva cerca de um quarto do tempo de transmissão. Portanto, a taxa de transferência média será quatro vezes menor. Naquela época, eu ainda não tinha testes de velocidade da interface serial do Arduino e, olhando para o futuro, posso dizer que, mesmo com o conversor Serial to USB CH340 mais comum, uma velocidade de 2 Mbps funciona de maneira estável.
Scanner CAN no Arduino
O primeiro escudo chegou para o clássico Arduino UNO. Sim, custa significativamente mais do que seus colegas menores, mas possui tudo o que você precisa e até dois botões.
Foi com ele que iniciei todos os experimentos. Montou um circuito simples com este escudo e uma tela de duas linhas de cristal líquido. O objetivo era exibir pelo menos alguns dados na tela. Eu ordenei através de várias bibliotecas para trabalhar com o barramento CAN no Arduino (direi imediatamente que a biblioteca correta e de trabalho é chamada de CAN-BUS Shield pelo Seeed Studio com o arquivo de cabeçalho mcp_can.h), alterei o ressonador de quartzo no escudo de 16 MHz (originalmente era de 8 MHz) - não havia dados.
Dois microcircuitos estão instalados na blindagem: o controlador de barramento CAN MCP2515 e o driver de barramento CAN TJA1050. Depois de ler a documentação e vários fóruns, decidi mudar o TJA1050 para um driver mais canônico MCP2551 e os dados apareceram. Talvez o TJA1050 estivesse com defeito inicialmente, pois era muito difícil cometer um erro ao conectá-lo a dois fios. Além disso, usei conectores OBD e DB9 para conexão.
Em algumas horas, um simples scanner CAN foi gravado, exibindo o número do pacote capturado, seu ID e até 8 bytes de dados para esse pacote no LCD.
Foi aqui que os botões do escudo foram úteis, que eu usei para alternar entre o número do pacote exibido.
Sobre os botõesEm geral, esses botões foram úteis para muitas coisas. Foi com eles que comecei a testar o controle de alguns dispositivos do carro.
O começo foi marcado, precisamos avançar para uma implementação mais interessante.
Sniffer CAN no Arduino
A tarefa foi bastante simples:
- aceitar pacote do barramento CAN
- colocamos os dados recebidos em nossa estrutura
- enviar estrutura através da porta serial
Não vi nenhum problema nas duas primeiras tarefas. A biblioteca forneceu uma interrupção ao receber o próximo pacote de dados e funções convenientes para receber dados. Mas decidi enviar dados para o computador através da biblioteca CyberLib, que elimina parte da sobrecarga de toda a plataforma Arduino, devido à qual você pode descarregar um pouco o processador para processar os dados. Mais tarde, essa biblioteca teve que ser abandonada.
Para garantir que os dados enviados sejam processados corretamente no lado do computador, um prefixo de quatro bytes 0xAA55AA55 é inserido no fluxo antes de cada próximo dado (por algum motivo, esses bytes foram lembrados nos últimos dois bytes do setor de inicialização do DOS, mas estavam em uma ordem diferente). A lógica é esta:
- o computador lê o fluxo inteiro da porta serial e encontra a sequência de prefixos desejada 0xAA55AA55 nele
- imediatamente após o prefixo, haverá 4 bytes do identificador de pacote
- além do comprimento dos dados deste pacote, ele controla o comprimento de todo o pacote
- até 8 bytes de dados
Com isso, a parte do software no Arduino, na época, foi concluída. Mais tarde, foi refeito significativamente, mas o conceito geral não mudou.
Também escrevi um gerador simples de pacotes de dados para depuração em depuração em casa - ele simplesmente envia pacotes com dados aleatórios para a porta serial, o que permite depurar o aplicativo em seu computador em condições confortáveis.
Na mesma época, chegaram os componentes menores do escudo Arduino Nano e Mini CAN.
Projetei um estojo pequeno, imprimi-o e coloquei todos os componentes dentro.
Lá fora, há um conector OBD de um lado e Mini USB do outro. No interior, há um interruptor para um resistor de terminação.
CAN sniffer no PC usando wxWidgets
Esbocei um rascunho simples de um programa em C #, que exibe os dados recebidos na Grade. E ele foi verificar o carro. Eu simplesmente não fui com o meu laptop, já que a bateria dele me mandou viver por um longo tempo e foi usada como um computador estacionário, mas peguei um netbook com um processador muito fraco. O que vi ... não vi nada. Ambos os núcleos são 100% carregados, a interface do aplicativo não responde. Mas no meu computador, que ainda é muito mais rápido que um netbook, com o gerador aleatório de pacotes, o aplicativo funcionou bem e exibiu dados. A partir disso, concluí que a plataforma .NET em computadores fracos não funcionaria para mim, pois eu poderia depurar em campo naquele momento apenas com esse netbook.
Anteriormente, usei a biblioteca wxWidgets em vários projetos e só tenho uma experiência agradável. É leve, não há necessidade de transportar várias bibliotecas e até plataforma cruzada, o que dá esperança de que a parte da interface do código possa ser transferida sem alterações significativas para outras plataformas. No final do artigo, haverá um link para o programa compilado, se não houver desejo de se preocupar com tudo isso.
Como instalar e compilar wxWidgets para Visual StudioInstalação e compilação1. Baixe o Windows Installer
wxWidgets e instale, por exemplo, na pasta C: \ wxWidgets
2. Crie uma variável de ambiente:
WXWIN = C: \ wxWidgets
3. Execute o prompt de comando do Visual Studio e vá para o diretório:
% WXWIN% \ build \ msw
4. Digite dois comandos para compilar:
nmake / f makefile.vc BUILD = depuração RUNTIME_LIBS = estática
nmake / f makefile.vc BUILD = libere RUNTIME_LIBS = estático
Configurando um projeto no Visual Studio1. No Visual Studio, crie um projeto Win32, com o parâmetro Empty project.
2. Nas propriedades do projeto para Toda a configuração, especifique os caminhos na seção de diretórios do VC ++:
Incluir Diretórios:
$ (WXWIN) \ incluir
$ (WXWIN) \ include \ msvc
Diretórios da biblioteca:
$ (WXWIN) \ lib \ vc_lib
3. Na seção C / C ++ - Geração de código, altere:
Biblioteca de Tempo de Execução para Depuração: / configuração do MTd
Biblioteca de tempo de execução para configurar o Release: / MT
4. Na seção Geral, altere:
Conjunto de Caracteres: Usar Conjunto de Caracteres Unicode
5. Para adicionar um ícone a um arquivo exe, você precisa adicionar um arquivo de recurso com o seguinte conteúdo:
#include "wx \ msw \ wx.rc"
ícone wxicon app_icon.ico
6. Além disso, se você precisar usar o UAC, na seção Vinculador - arquivo de manifesto:
Nível de execução do UAC: requireAdministrator
O primeiro protótipo implementado em C ++ e wxWidgets mostrou que mesmo um netbook lida com a exibição de dados em uma tabela, e comecei a desenvolver o que havia planejado.
Arquitetonicamente, o programa consiste em dois fluxos: interface e fluxo de trabalho com uma porta serial. Nenhum algoritmo incrivelmente interessante foi aplicado. O código é bastante comentado e deve ser bem direto. Um link para a fonte estará no final do artigo.
A primeira coisa que foi feita foi a coloração das células de dados na tabela de acordo com a limitação da obtenção desses dados. Já no primeiro protótipo, olhando para 17 linhas de dados de valores em constante mudança, percebi que era necessário distinguir de alguma forma entre dados novos e dados que não mudam ou raramente mudam. Ele fez uma coloração em duas etapas:
- dados pela primeira vez são destacados em fundo de célula verde
- os dados que chegam repetidamente e mais são destacados em vermelho, que desaparece gradualmente para branco se esses dados não mudarem mais
Imediatamente ficou claro quais células não eram usadas, quais continham os contra-sinais. A busca por valores variáveis de interesse é bastante simplificada. A seguir, todas as imagens são animadas. Se a animação não funcionar no artigo (em alguns navegadores móveis) - clique na imagem para abrir a versão completa da animação.

Então, eu ainda queria verificar se a porta serial lida com o fluxo de dados. Para fazer isso, no lado do Arduino, adicionei contadores para o número de pacotes recebidos e um contador de bytes no pacote. Esses contadores são enviados ao computador em um pacote com o identificador 0x000. Ao receber esses dados, o programa não os exibe em uma tabela, mas os exibe em campos de informações separados na parte superior. Os resultados foram até bastante agradáveis. Em média, até 750 pacotes / s são recebidos a uma velocidade de até 9,5 kB / s, e é nessa região que até 80 kbit / s, o que é bastante possível para uma porta serial. Mas, mesmo assim, a troca de dados é configurada por padrão a 500 kbps, permitindo um estoque melhor.
A adição da capacidade de gravar dados no log apareceu após eu conectar o adaptador de diagnóstico ELM327 em paralelo à interface OBD e conectá-lo ao telefone, tentando ler vários dados. Os dados foram tão rápidos que era impossível vê-los. Depois de registrar tudo isso em um diário, você pode sentar-se com calma e ver os dados transmitidos. Para fazer isso, mesmo dados de texto ASCII podem ser gravados no log. Você também pode selecionar o tipo de arquivo, o caractere delimitador e configurar o filtro de pacotes clicando no identificador de pacote especificado na tabela e clicando no botão "Adicionar ID ao filtro" (por padrão, todos os dados são gravados) se todos os dados forem redundantes.
Foi então que percebemos que todos os aplicativos telefônicos que executam todos os tipos de "diagnósticos" através do pacote ELM327 e o telefone não se comunicam diretamente com o barramento CAN do veículo. Eles apenas usam a funcionalidade de diagnóstico OBD através do barramento CAN acessando o CAN ID 0x7E0. Geralmente este é o endereço do controlador do motor (ECU), a resposta é fornecida em um pacote com o identificador 0x7E8. Mas todos os outros pacotes de dados são os chamados Fornecedores Específicos e nenhum fabricante simplesmente os abre (embora exista um exemplo: a
Ford lançou um SDK para seus carros ).
Continuando a estudar o que está sendo transmitido nesses pacotes, tive outra ideia: quando clico em uma célula da tabela, na janela do programa à direita, exibe o valor binário e decimal desse byte, além de pegar o próximo byte e adicionar à palavra. Em seguida, multiplique esta palavra por um determinado coeficiente e obtenha um resultado decimal. Não parece muito claro, mas em conexão com o que foi feito: a velocidade do motor vem no pacote CAN ID 0x180, nos dois primeiros bytes. Esses dois bytes fornecem uma determinada palavra que é proporcional às voltas. Se o significado desta palavra é dividido por 8, o momento atual é obtido. Portanto, um fator de 0,125 é indicado, como o recíproco de 8. Em seguida, essa palavra é visualizada em um gráfico com ajuste dinâmico em amplitude. Em princípio, o multiplicador pode ser pesquisado na ordem inversa: encontrei células muito semelhantes à velocidade do motor ou qualquer outra coisa de acordo com o cronograma, após o qual o multiplicador é ajustado para obter valores reais.

Bem, a representação binária permite procurar vários indicadores de bits. Por exemplo, a busca por indicadores indicadores de direção é reduzida para ativá-los e observar qual célula começa a mudar, no exemplo abaixo, é CAN ID 0x481 byte 2. Depois disso, clicar em uma célula exibe seu valor binário no campo correspondente, onde os dois inferiores são já visíveis bits (esquerda, direita e se juntos - um alarme).

E, finalmente, eu precisava enviar alguns dados de controle para o barramento CAN e ver a reação a esses comandos. Um código foi adicionado ao programa Arduino que recebe dados do computador e é transferido para o barramento CAN. Foi nessa fase que o CyberLib teve que ser abandonado, pois não tinha suporte para interromper o recebimento de dados no buffer da porta serial. No programa no computador, adicionei vários campos de texto nos quais você pode inserir vários parâmetros e uma tabela para visualizar a resposta do atuador. O exemplo abaixo mostra os comandos de controle para ativar / desativar a primeira velocidade do ventilador de refrigeração (0x0A) e para ativar / desativar a embreagem do ar condicionado (0x0B).

Sumário
Praticamente nenhum lugar para encontrar uma descriptografia completa dos dados dos fabricantes, especialmente os oficiais. Na melhor das hipóteses, será a pesquisa de outra pessoa no âmbito da implementação de alguma função adicional. O sniffer CAN pode ajudá-lo a encontrar esses dados. Consegui encontrar cerca de 40 parâmetros diferentes do carro e, para fins de experimento, com base nos dados recebidos, fiz meu próprio controle do ventilador de refrigeração.
Espero que tudo isso seja útil não apenas para mim.