Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

IoT4Car

Componentes e suprimentos

Arduino MKR1000
× 1
Conversor de nível lógico SparkFun - bidirecional
× 1
SparkFun OBD-II UART
× 1
Cabo SparkFun OBD-II para DB9
× 1

Aplicativos e serviços online

Arduino IDE
freeboard
dweet

Sobre este projeto





Antecedentes


Ao dirigir seu veículo, olhando para o painel, você já pensou em coletar as leituras do medidor e fazer algumas análises? Esses dados podem conter tesouros escondidos. Para indivíduos, pode refletir seus hábitos de direção, pode dizer sua velocidade, seu mpg médio, quantos semáforos você tem e seu tempo de espera em cada cruzamento. Para as empresas, esses dados são essenciais para o monitoramento em tempo real no gerenciamento de frotas. A condição do veículo, a distribuição da carga de trabalho, a eficiência da gasolina e até a localização do veículo podem ser enviadas de volta para um sistema de controle central por meio da nuvem. As empresas podem usar o aprendizado de máquina para alimentar os dados em um modelo de treinamento para prever o custo e até mesmo analisar as características do motorista. Como a IoT está se espalhando amplamente, os aplicativos acima não estarão longe. Com as placas Arduino MKR, voltadas para aplicativos IoT, você pode construir um dispositivo que se comunica com seu carro e carrega dados telemétricos na nuvem sozinho. Isso não é legal?





Falando com um veículo


Precisamos de uma interface para acessar o sistema do veículo. Onde podemos hackear o carro? A resposta é interface OBD-II.

O que é OBD-II?

O On-Board Diagnostics (OBD) é um sistema de autodiagnóstico integrado no veículo, por meio do qual podemos nos comunicar com nossos carros. Foi introduzido pela primeira vez nos Estados Unidos em 1994 e tornou-se um requisito em todos os veículos americanos de 1996 e mais recentes. Outros países, incluindo Canadá, partes da União Europeia, Japão, Austrália e Brasil adotaram legislação semelhante. OBD-II (segunda geração) tem cinco protocolos de sinalização, e Controller Area Network (CAN bus) é um deles. O barramento CAN deve ser implementado em todos os carros dos EUA desde 2008. Há uma grande introdução do OBDII fornecido pela CSS Electronics no Youtube. Neste projeto, acessaremos os dados através das interfaces OBD-II de 16 pinos.

Meu controlador

Arduino é uma excelente plataforma para amadores, criadores e profissionais. Possui uma variedade de placas destinadas a diferentes aplicações. Aqui eu uso a placa Arduino MKR WiFi 1000 devido à sua capacidade WiFi. Você também pode usar outras placas de que goste. Eu recomendaria o Arduino MKR GSM 1400, simplesmente porque o GSM cobre áreas muito mais amplas do que o WiFi. Mas não se preocupe, mesmo com WiFi podemos ter acesso à internet ao longo das estradas. Vou mostrar a você a solução alternativa.

A placa de interpretação

Embora o próprio Arduino tenha muitos I / Os e várias bibliotecas, ainda precisamos de uma placa que possa traduzir os protocolos OBD em uma linguagem que o Arduino possa reconhecer. A placa que uso é a Placa UART SparkFun OBD-II.



Esta placa permite que você interaja com o barramento OBD-II do seu carro. Ele fornece uma interface serial usando o conjunto de comandos ELM327 e oferece suporte a todos os principais padrões OBD-II, como CAN. A placa contém um chip STN1110, que é um interpretador OBD para UART que pode ser usado para converter mensagens entre qualquer um dos protocolos OBD-II atualmente em uso e UART.

Porém, deve-se ressaltar que a placa de interpretação possui uma tensão de E / S de 5 V, o que pode danificar as E / S da placa Arduino MKR, caso conecte-as diretamente. O Arduino MKR WiFI 1000 funciona com uma tensão mais baixa e sua tensão de E / S é 3,3 V. Portanto, um deslocador de nível é necessário para converter o sinal de 5 V para 3,3 V e vice-versa. Abaixo está a imagem da mudança de nível que eu uso.



Conectar

Conectar o circuito é muito fácil. Simplesmente conectando seu Arduino MRK pino 13 Rx e pino 14 Tx, aos pinos Tx e Rx da placa UART OBD-II através do deslocador de nível. Claro, você precisa conectar o aterramento das duas placas.

Para facilitar a depuração e a demonstração, também conectei uma tela LCD 1602 ao Arduino para exibir os dados em tempo real. A fiação do LCD para o Arduino pode ser encontrada neste tutorial e, portanto, não será elaborada aqui.

Abaixo está a imagem da conexão do breadboard. As linhas verdes são para os fios que conectam o Arduino e a placa UART OBD-II, enquanto as linhas amarelas são para os fios que conectam o Arduino e o LCD. O esquema também está disponível no anexo.

A conexão real é um pouco confusa devido à área limitada do breadboard, mas segue o esquema acima. Incluí o cabo micro USB e ODB-II para DB9 na imagem.

Serial1 não Serial

Certo, é hora de programar nossa placa Arduino MKR. Como minha placa Arduino MKR fala com a placa de interpretação por meio do UART, não há necessidade de instalar bibliotecas de terceiros. Enviar comandos para a placa de interpretação é simplesmente como se comunicar com o Monitor Serial. A única coisa que quero enfatizar é que a porta serial associada aos pinos 13 e 14 é Serial 1 ! Placa Arduino MKR Porta serial refere-se à sua porta USB que é usada para se comunicar com o seu computador. Não se esqueça de inicializar o Serial 1 porta na função setup ().
  Serial1.begin (9600);  

E use Serial 1 para empurrar o comando para a placa de interpretação.
  Serial1.println (mensagem);  

Mensagens

Como você pode ver, uso a variável "mensagem" para armazenar os comandos. Os comandos OBD são compostos de códigos hexadecimais escritos em caracteres ASCII. Os primeiros dois números hexadecimais referem-se ao modo de serviço a ser usado. Existem 10 serviços de diagnóstico descritos no último padrão OBD-II SAE J1979. Como estamos interessados ​​no monitoramento em tempo real, usaremos apenas 01 código para mostrar os dados atuais neste projeto.

Qualquer número hexadecimal após o modo de serviço representa o ID do parâmetro (PID) para alcançar funções especiais. Abaixo está a captura de tela dos PIDs no modo 01 serviço. Mais informações podem ser encontradas na Wikipedia.

Neste projeto, demonstrarei como obter a velocidade do carro, a rotação do motor, o nível de combustível e a temperatura do líquido de arrefecimento do motor. Os comandos OBD para essas quatro funções são:
  • 010D // velocidade do carro
  • 010C // RPM do motor
  • 012F // nível de combustível
  • 0105 // temperatura do refrigerante.

Decodifique os dados

Uma vez que os comandos são enviados, a placa Arduino MKR ouvirá a porta Serial 1 para qualquer resposta. É melhor colocar um atraso de 200 ms após o envio dos comandos. Eu uso o seguinte código para receber uma resposta.
  void getResponse (void) {while (Serial1.available ()> 0) {// Comece verificando se recebemos o caractere de fim de mensagem ('\ r'). if (Serial1.peek () =='\ r') {// chegar ao final da mensagem, limpar o buffer Serial inChar =Serial1.read (); rxData [rxIndex] ='\ 0'; // Reinicia o índice do buffer para que o próximo caractere volte ao início da string rxIndex =0; } // Se não obtivemos o final do caractere da mensagem, basta adicionar o novo caractere à string else {// Obter o novo caractere da porta serial:inChar =Serial1.read (); // adiciona o novo caractere à string e aumenta a variável de índice:rxData [rxIndex ++] =inChar; }}}  

A resposta do quadro de intérpretes segue o formato

"> 1 Dados PIDs Repetidos"

Por exemplo, na imagem acima, envio "010D" para obter a velocidade do carro. A resposta é "> 1 0D 00". Os primeiros 5 caracteres mostram que o carro recebe o comando e repete o PID 0x0D de volta. Os últimos dois dígitos retornam os dados de velocidade 0x00.

Então eu envio "010C" para obter o RPM do motor, a resposta "> 1 0C" mostra o reconhecimento do comando, o dado 0x098C é 4 vezes o valor do RPM do motor em hexadecimal. 0x098C / 4 =611 dec, então a rotação do motor é 611 rpm.

Depois disso, envio o comando "012F" para obter o nível de combustível e recebo os dados 0x1D. O nível de combustível é calculado como 0x1D / 255 * 100 =11% dec.

O comando final é "0105", o que me dá a temperatura do líquido de arrefecimento 0x79. A temperatura real é 0x79 - 40 =81 graus C dec. Em seguida, a seqüência de comando se repete.

Como você pode ver, a linha de resposta tem espaços entre dois dígitos hexadecimais e os primeiros 5 dígitos simplesmente repetem os comandos. Portanto, os dados reais começam no 6º caractere (o primeiro começa no índice 0).

Na programação e depuração, um monitor serial é útil, mas quando se trata de uma aplicação real, uma tela LCD é mais portátil e atende aos requisitos de energia da IoT. Basta substituir o monitor serial por uma tela LCD para monitorar os dados do carro em tempo real. Abaixo está a foto de usar o projeto no meu próprio carro.





Nuvem nossos dados


A vantagem do Arduino MKR sobre o UNO é a acessibilidade à Internet. Visando a aplicação IoT, o Arduino MKR tornará as indústrias mais inteligentes e conectivas. Nas aplicações automotivas, MKR WiFi 1000 pode não ser a melhor placa já que o sinal WiFi é raro em ambientes externos, mas eu uso meu celular como um hotspot pessoal, então não é um problema.

Existem muitas outras plataformas de nuvem para armazenar, visualizar e pós-processar os dados. Você pode escolher o que quiser. Vou usar dweet.io e freeboard.io como exemplo. Dweet.io fornece API para a qual você pode enviar dados. Freeboard.io tem identificadores para pegar os dados do dweet.io e visualizá-los. Existem vários tutoriais para configurar dweet.io e freebboard.io, então não vou entrar em detalhes novamente. Se você estiver interessado, aqui estão alguns exemplos, exemplo 1, exemplo 2.

O código de envio de dados é exibido abaixo como uma ilustração de como criar comandos dweet.
  void httpRequest () {client.stop (); // cria string de dados para enviar ao freeboard if (client.connect (server, 80)) {Serial.println ("Connected"); String data ="POST / dweet / for / mkr1000? RPM ="; data.concat (vRPM); // faz upload do motor RPM data.concat ("&Speed ​​="); data.concat (vSpeed); // carregue a velocidade do carro data.concat ("&Fuel ="); data.concat (vFuel); // carregue o nível de combustível data.concat ("&Temp ="); data.concat (vTemp); // faz upload da temperatura do refrigerante client.println (data); client.println ("Host:https://www.dweet.io"); client.println ("Conexão:fechar"); // fim da conexão client.println (); } else {lcd.clear (); lcd.setCursor (0,0); lcd.println ("Falha na conexão"); }}  

No freeboard.io, precisamos criar um novo painel e, dentro dele, criar uma nova fonte de dados. Vincule esta fonte de dados ao seu dweet.io que você definiu no código. No meu caso, é mkr1000. Em seguida, crie um novo widget de medidor que usaremos para exibir os dados. Dê um nome a ele e vincule-o a uma de nossas variáveis. Abaixo está uma captura de tela do meu painel. Mostra VELOCIDADE, RPM, NÍVEL DE COMBUSTÍVEL e TEMPERATURA DO REFRIGERANTE.





Conclusão


Experimentei as pranchas no meu próprio carro e funcionou bem. Estou trabalhando no projeto de um PCB que inclui todas as funções em um circuito integrado. Com sorte, escreverei mais tutoriais no futuro. Posso incluir uma demonstração em vídeo também. Lamento desta vez, mas não consegui gravar o vídeo, além de dirigir meu carro. E você também deve ter cuidado ao depurar seu código enquanto dirige na rua!

A placa Arduino MKR WiFi é boa o suficiente para esta aplicação. Se eu tiver mais placas, acho que posso tentar a placa MKR GSM 1400. Sinta-se à vontade para usar outras placas IoT com este tutorial e me dê sua opinião.

Trabalhar no projeto é divertido e educativo. Gosto da sensação de depurar um problema. Também é um prazer compartilhar o que sei na web. Obrigado por ler. Deixe-me saber se você tiver alguma dúvida ou comentário.

Código

  • IoT4Car_code
IoT4Car_code C / C ++
Este programa se comunicará com o veículo usando a placa OBDII-UART, exibirá os resultados no LCD e fará o upload para a plataforma IoT da placa livre
 / ** OBDII-UART-Serial versão 9 * Este programa se comunicará com o veículo usando o OBDII - Placa UART, * e exibir os resultados no LCD, e fazer upload para a plataforma IoT da placa livre * * Autor:zhaoshentech * Atualizado:27-08-2018 * * atualizações:* v3:modificou a função getResponse () para que o buffer receba a resposta correta. * adicione getRPM () para obter a rotação do motor do veículo. * v4:adicione a função getSpeed ​​() para obter a velocidade do veículo * v5:adicione o módulo LCD e exiba a velocidade e RPM no LCD * v6:é a versão wi-fi * v7:é a versão não wi-fi e não serial. Remova a inicialização serial, * para que a placa possa funcionar sem um computador. * V8:é a versão não wi-fi e não serial. Adicione o nível de combustível e a temperatura do líquido de arrefecimento. * Reorganize o local do visor. * V9:é a versão wi-fi, não serial. Velocidade Upolad, RPM, nível de combustível e temperatura do líquido refrigerante * * Conexão do circuito LCD:* LCD RS pino para pino digital 12 * LCD habilitar pino para pino digital 11 * pino LCD D4 para pino digital 5 * pino LCD D5 para pino digital 4 * LCD D6 pin to digital pin 3 * LCD D7 pin to digital pin 2 * LCD R / W pin to ground * 10 K potencialmeter:* termina em + 5V e aterramento * wiper to LCD VO pin (pin 3) * ///// //////////////////////////////////////////////////////// ////// WiFi related ////////////////////////////////////////// /////////////////#include#includechar ssid [] ="SEU SSID WIFI"; // wi-fi IDchar pass [] ="SEU WIFI PSWD"; // servidor wi-fi passwordchar [] ="www.dweet.io"; // freeboard e dweet Settingsunsigned long lastConnectionTime =0; // rastreia o tempo da última conexãoconst unsigned long postedInterval =10L * 1000L; // publica dados a cada 10 segundosWiFiClient client; // Inicializa o wi-fi clientint status =WL_IDLE_STATUS; // o status do rádio WiFi // inclui o libaray LDC # include  const int rs =12, en =11, d4 =5, d5 =4, d6 =3, d7 =2; LiquidCrystal lcd (rs, en, d4, d5, d6, d7); // Este é um buffer de caracteres que armazenará os dados da porta serial:char rxData [20]; char rxIndex =0; char inChar =0; String message; // Variáveis para manter a velocidade e os dados RPM:int vSpeed ​​=0; int vRPM =0; int vFuel =0; int vTemp =0; void setup () {// Configurar o número de colunas e linhas do LCD:lcd.begin ( 16,2); lcd.clear (); // verifique a presença do escudo:if (WiFi.status () ==WL_NO_SHIELD) {lcd.println ("WiFi não está pronto"); enquanto (verdadeiro); } // tentativa de conexão à rede WiFi:while (status! =WL_CONNECTED) {lcd.clear (); lcd.setCursor (0, 0); lcd.println ("Conectando WiFi ..."); status =WiFi.begin (SSID, aprovação); // aguarde 5 segundos pela conexão:delay (5000); } lcd.setCursor (0, 1); lcd.println ("Conectado!"); // Serial1 é a porta acutal para falar com o veículo Serial1.begin (9600); resetBuffer ();} void loop () {while (status! =WL_CONNECTED) {lcd.clear (); lcd.setCursor (0,0); // Conectar à rede WPA / WPA2 Wi-Fi Serial.println ("Conectando ao Wifi"); lcd.println ("Conectar WiFi ..."); status =WiFi.begin (SSID, aprovação); // aguarde 10 segundos pelo atraso de conexão (5000); } getSpeed ​​(); getRPM (); getFuel (); getCoolTemp (); if (millis () - lastConnectionTime> postagemInterval) {httpRequest (); lastConnectionTime =millis (); }} // getRPM data envia o comando "010C" para a porta Serial1 // e chama getResponse () para coletar os dados. Em seguida, ele imprime // os dados RPM no Serial Monitor.void getRPM (void) {message ="010C"; Serial1.println (mensagem); atraso (200); // limpar a linha atual para (int i =8; i <16; ++ i) {lcd.setCursor (i, 0); // 0 linha, i coluna lcd.write (''); } lcd.setCursor (8,0); // primeira linha, segunda metade na tela LCD // wait reponse getResponse (); // A resposta RPM dividida por 4 fornece o valor correto. vRPM =((strtol (&rxData [6], 0,16) * 256) + strtol (&rxData [9], 0,16)) / 4; lcd.print (vRPM); lcd.print ("rpm");} void getSpeed ​​(void) {message ="010D"; Serial1.println (mensagem); atraso (200); // limpar a linha atual:for (int i =0; i <8; ++ i) {lcd.setCursor (i, 0); // 0 linha, i coluna lcd.write (''); } lcd.setCursor (0,0); // primeira linha da primeira metade na tela LCD // aguarde a resposta do carro getResponse (); vSpeed ​​=strtol (&rxData [6], 0, 16); // na unidade de km / h vSpeed ​​=vSpeed ​​* 0.621371; // na unidade de mph lcd.print (vSpeed); lcd.print ("mph");} void getFuel (void) {message ="012F"; Serial1.println (mensagem); atraso (200); // limpar a linha atual:for (int i =0; i <8; i ++) {lcd.setCursor (i, 1); // 1ª linha, coluna i lcd.write (''); } lcd.setCursor (0, 1); // primeira metade da segunda linha na tela LCD // aguarde a resposta do carro getResponse (); vFuel =strtol (&rxData [6], 0, 16); // na escala de 255 // vFuel =244; // depurar o uso vFuel =1.0 * vFuel / 255 * 100; // na escala de 100 lcd.print (vFuel); lcd.print ("%"); //Serial.println(vFuel); // depurar o uso} void getCoolTemp (void) {message ="0105"; Serial1.println (mensagem); atraso (200); // limpar a linha atual:for (int i =8; i <16; i ++) {lcd.setCursor (i, 1); // 1ª linha, coluna i lcd.write (''); } lcd.setCursor (8, 1); // segunda metade da segunda linha na tela LCD // aguarde a resposta do carro getResponse (); vTemp =strtol (&rxData [6], 0, 16); // na unidade de C, mas deslocado em 40 graus vTemp =vTemp - 40; // deslocado por 0 lcd.print (vTemp); // imprime o grau C lcd.write (0xDF); lcd.print ("C");} // A função getResponse coleta dados de entrada do UART no buffer rxData // e sai quando a resposta é transferida. Uma vez que a string de retorno de carro // é detectada, o buffer rxData é terminado em nulo (para que possamos tratá-lo como uma string) // e o índice rxData é redefinido para 0 para que a próxima string possa ser copiada.void getResponse (void ) {while (Serial1.available ()> 0) {// Comece verificando se recebemos o caractere de fim de mensagem ('\ r'). if (Serial1.peek () =='\ r') {// chegar ao final da mensagem, limpar o buffer Serial inChar =Serial1.read (); rxData [rxIndex] ='\ 0'; // Reinicia o índice do buffer para que o próximo caractere volte ao início da string rxIndex =0; } // Se não obtivemos o final do caractere da mensagem, basta adicionar o novo caractere à string else {// Obter o novo caractere da porta serial:inChar =Serial1.read (); // adiciona o novo caractere à string e aumenta a variável de índice:rxData [rxIndex ++] =inChar; }}} void resetBuffer (void) {for (int i =0; i <20; i ++) {rxData [i] =0; }} void httpRequest () {client.stop (); // cria string de dados para enviar ao freeboard if (client.connect (server, 80)) {Serial.println ("Connected"); String data ="POST / dweet / for / mkr1000? RPM ="; data.concat (vRPM); // faz upload do motor RPM data.concat ("&Speed ​​="); data.concat (vSpeed); // carregue a velocidade do carro data.concat ("&Fuel ="); data.concat (vFuel); // carregue o nível de combustível data.concat ("&Temp ="); data.concat (vTemp); // faz upload da temperatura do refrigerante client.println (data); client.println ("Host:https://www.dweet.io"); client.println ("Conexão:fechar"); // fim da conexão client.println (); } else {lcd.clear (); lcd.setCursor (0,0); lcd.println ("Falha na conexão"); }} 

Esquemas

Conecte Arduino MKR WiFi 1000, placa SparkFun OBD-II UART, SparkFun Logic Level Shifter e LCD 1602 frizling_schematics_M8kF26dafQ.fzz

Processo de manufatura

  1. Matrícula
  2. Sistema de freio antitravamento
  3. O que é um trem de força?
  4. O que é um alternador?
  5. Evitar Obstáculos usando Inteligência Artificial
  6. Controlador de jogo Arduino
  7. Traje da nuvem
  8. O que é um Chassi Ground?
  9. Layout do chassi de um veículo
  10. Entendendo a fiação do veículo