Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

IoT4Car

Composants et fournitures

Arduino MKR1000
× 1
Convertisseur de niveau logique SparkFun - Bidirectionnel
× 1
SparkFun OBD-II UART
× 1
Câble SparkFun OBD-II vers DB9
× 1

Applications et services en ligne

Arduino IDE
franc-bord
dweet

À propos de ce projet

Contexte

Au volant de votre véhicule, en regardant votre tableau de bord, avez-vous déjà pensé à collecter les relevés des compteurs et à faire des analyses ? Ces données peuvent contenir des trésors cachés. Pour les particuliers, il peut refléter vos habitudes de conduite, il peut vous indiquer votre vitesse, votre mpg moyen, le nombre de feux de circulation que vous avez et votre temps d'attente à chaque croisement. Pour les entreprises, ces données sont essentielles pour le suivi en temps réel de la gestion de flotte. L'état du véhicule, la répartition de la charge de travail, l'efficacité de l'essence et même l'emplacement du véhicule peuvent tous être renvoyés à un système de contrôle central via le cloud. Les entreprises peuvent utiliser l'apprentissage automatique pour intégrer les données dans un modèle de formation afin de prédire le coût et même d'analyser les caractéristiques du conducteur. Comme l'IoT se répand largement, les applications ci-dessus ne seront pas loin. Avec les cartes Arduino MKR, ciblant les applications IoT, vous pouvez créer vous-même un appareil qui communique avec votre voiture et télécharge des données télémétriques dans le cloud. N'est-ce pas cool ?

Parler à un véhicule

Nous avons besoin d'une interface pour accéder au système du véhicule. Où peut-on pirater la voiture ? La réponse est l'interface OBD-II.

Qu'est-ce que l'OBD-II ?

Le diagnostic embarqué (OBD) est un système d'autodiagnostic intégré à un véhicule, grâce auquel nous pouvons communiquer avec nos voitures. Il a été introduit pour la première fois aux États-Unis en 1994 et est devenu une exigence sur tous les véhicules américains de 1996 et plus récents. D'autres pays, dont le Canada, certaines parties de l'Union européenne, le Japon, l'Australie et le Brésil ont adopté une législation similaire. OBD-II (deuxième génération) a cinq protocoles de signalisation, et Controller Area Network (CAN bus) est l'un d'entre eux. Le bus CAN doit être implémenté dans toutes les voitures américaines depuis 2008. Il y a une excellente introduction d'OBDII fournie par CSS Electronics sur Youtube. Dans ce projet, nous accéderons aux données via les interfaces OBD-II à 16 broches.

Mon contrôleur

Arduino est une excellente plate-forme pour les amateurs, les fabricants et les professionnels. Il dispose d'une variété de cartes ciblant différentes applications. Ici, j'utilise la carte Arduino MKR WiFi 1000 en raison de sa capacité WiFi. Vous pouvez également utiliser d'autres tableaux que vous aimez. Je recommanderais Arduino MKR GSM 1400, simplement parce que le GSM couvre des zones beaucoup plus larges que le WiFi. Mais ne vous inquiétez pas, même avec le WiFi, nous pouvons avoir accès à Internet le long des routes. Je vais vous montrer la solution de contournement.

Le tableau d'interprétation

Bien qu'Arduino lui-même possède de nombreuses E/S et de nombreuses bibliothèques, nous avons toujours besoin d'une carte capable de traduire les protocoles OBD dans un langage qu'Arduino peut reconnaître. La carte que j'utilise est la carte SparkFun OBD-II UART.

Cette carte vous permet de vous interfacer avec le bus OBD-II de votre voiture. Il vous fournit une interface série utilisant le jeu de commandes ELM327 et prend en charge toutes les principales normes OBD-II telles que CAN. La carte contient une puce STN1110, qui est un interpréteur OBD vers UART qui peut être utilisé pour convertir des messages entre l'un des protocoles OBD-II actuellement utilisés et UART.

Cependant, il convient de souligner que la carte d'interprétation a une tension d'E/S de 5 V, ce qui peut endommager les E/S de la carte Arduino MKR si vous les connectez directement. Arduino MKR WiFI 1000 fonctionne à une tension inférieure et sa tension d'E/S est de 3,3 V. Par conséquent, un décaleur de niveau est nécessaire pour convertir le signal de 5 V à 3,3 V et vice versa. Ci-dessous se trouve l'image du changement de niveau que j'utilise.

Raccordez-le

Le branchement du circuit est assez simple. Connectez simplement vos broches 13 Rx et 14 Tx d'Arduino MRK aux broches Tx et Rx de la carte UART OBD-II via le décaleur de niveau. Bien sûr, vous devez connecter la masse des deux cartes ensemble.

Pour faciliter le débogage et la démonstration, j'ai également connecté un écran LCD 1602 à Arduino pour afficher les données en temps réel. Le câblage LCD vers Arduino peut être trouvé dans ce didacticiel et ne sera donc pas développé ici.

Vous trouverez ci-dessous l'image de la connexion de la maquette. Les lignes vertes sont pour les fils reliant l'Arduino et la carte UART OBD-II, tandis que les lignes jaunes sont pour les fils reliant l'Arduino et l'écran LCD. Le schéma est également disponible en pièce jointe.

La connexion réelle est un peu désordonnée en raison de la surface limitée de la planche à pain, mais elle suit le schéma ci-dessus. J'ai inclus le câble micro USB et ODB-II vers DB9 dans l'image.

Série1 pas Série

Très bien, il est temps de programmer notre carte Arduino MKR. Étant donné que ma carte Arduino MKR parle avec la carte d'interprétation via UART, il n'est pas nécessaire d'installer des bibliothèques tierces. L'envoi de commandes à la carte d'interprétation revient simplement à communiquer avec Serial Monitor. La seule chose que je veux souligner est que le port série associé aux broches 13 et 14 est Serial 1 ! Carte Arduino MKR Port série fait référence à son port USB qui est utilisé pour communiquer avec votre ordinateur. N'oubliez pas d'initialiser Serial 1 port dans la fonction setup().

 Serial1.begin(96000); 

Et utilisez Série 1 pour pousser la commande au tableau d'interprétation.

 Serial1.println(message); 

Messages

Comme vous le voyez, j'utilise la variable "message" pour stocker les commandes. Les commandes OBD sont constituées de codes hexadécimaux écrits en caractères ASCII. Les deux premiers nombres hexadécimaux font référence au mode de service à utiliser. Il existe 10 services de diagnostic décrits dans la dernière norme OBD-II SAE J1979. Comme nous nous intéressons au suivi en temps réel, nous n'utiliserons que 01 code pour afficher les données actuelles dans ce projet.

Tout nombre hexadécimal après le mode de service représente l'ID de paramètre (PID) pour réaliser des fonctions spéciales. Ci-dessous se trouve la capture d'écran des PID en mode service 01. Plus d'informations peuvent être trouvées dans Wikipedia.

Dans ce projet, je montrerai comment obtenir la vitesse de la voiture, le régime du moteur, le niveau de carburant et la température du liquide de refroidissement du moteur. Les commandes OBD pour ces quatre fonctions sont:

  • 010D // vitesse de la voiture
  • 010C // RPM moteur
  • 012F // niveau de carburant
  • 0105 // température du liquide de refroidissement.

Décoder les données

Une fois les commandes envoyées, la carte Arduino MKR écoutera le port série 1 pour toute réponse. Il est préférable de mettre un délai de 200 ms après l'envoi des commandes. J'utilise le code suivant pour recevoir une réponse.

void getResponse(void){ while(Serial1.available()> 0) { // Commencez par vérifier si nous avons reçu le caractère de fin de message ('\r'). if(Serial1.peek() =='\r'){ // atteint la fin du message, efface le tampon série inChar =Serial1.read(); rxData[rxIndex] ='\0'; // Réinitialise l'index du tampon pour que le caractère suivant revienne au début de la chaîne rxIndex =0; } // Si nous n'avons pas obtenu la fin du caractère du message, ajoutez simplement le nouveau caractère à la chaîne else{ // Obtenez le nouveau caractère du port série :inChar =Serial1.read(); // ajoute le nouveau caractère à la chaîne et augmente la variable d'index :rxData[rxIndex++] =inChar; } }} 

La réponse du tableau d'interprétation suit le format

"> 1 Données PID répétées"

Par exemple, dans la capture d'écran ci-dessus, j'envoie "010D" pour obtenir la vitesse de la voiture. La réponse est ">1 0D 00". Les 5 premiers caractères indiquent que la voiture reçoit la commande et répète le PID 0x0D en retour. Les deux derniers chiffres renvoient les données de vitesse 0x00.

Ensuite, j'envoie "010C" pour obtenir le RPM du moteur, la réponse ">1 0C" montre l'accusé de réception de la commande, la donnée 0x098C est 4 fois la valeur du RPM du moteur en hexadécimal. 0x098C / 4 =611 déc, donc le régime moteur est de 611 tr/min.

Après cela, j'envoie la commande "012F" pour obtenir le niveau de carburant et j'obtiens les données 0x1D. Le niveau de carburant est calculé comme 0x1D / 255 * 100 =11% déc.

La dernière commande est "0105", ce qui me donne la température du liquide de refroidissement 0x79. La température réelle est 0x79 - 40 =81 degrés C déc. Ensuite, la séquence de commandes se répète.

Comme vous pouvez le voir, la ligne de réponse comporte des espaces entre deux chiffres hexadécimaux et les 5 premiers chiffres répètent simplement les commandes. Par conséquent, les données réelles commencent à partir du 6ème caractère (le premier commence à partir de l'index 0).

Lors de la programmation et du débogage, un moniteur série est utile, mais lorsqu'il s'agit d'une application réelle, un écran LCD est plus portable et répond aux exigences de puissance de l'IoT. Remplacez simplement le moniteur série par un écran LCD, vous pouvez surveiller les données de votre voiture en temps réel. Ci-dessous se trouve la photo de l'utilisation du projet dans ma propre voiture.

Cloud nos données

L'avantage de l'Arduino MKR par rapport à UNO est son accessibilité à Internet. En ciblant les applications IoT, Arduino MKR rendra les industries plus intelligentes et plus connectives. Dans les applications automobiles, MKR WiFi 1000 n'est peut-être pas la meilleure carte car le signal WiFi est rare dans un environnement extérieur, mais j'utilise mon téléphone portable comme point d'accès personnel, ce n'est donc pas un problème.

Il existe de nombreuses autres plates-formes cloud pour stocker, afficher et post-traiter les données. Vous pouvez choisir ce que vous voulez. Je vais utiliser dweet.io et freeboard.io comme exemple. Dweet.io fournit une API à laquelle vous pouvez envoyer des données. Freeboard.io a des poignées pour prendre les données dweet.io et les visualiser. Il existe plusieurs tutoriels pour configurer dweet.io et freebboard.io, je ne développerai donc pas à nouveau. Si vous êtes intéressé, voici quelques exemples, exemple 1, exemple 2.

Le code push de données est présenté ci-dessous à titre d'illustration de la création de commandes Dweet.

void httpRequest() { client.stop(); // crée une chaîne de données à envoyer au franc-bord if (client.connect(server, 80)){ Serial.println("Connected"); Données de chaîne ="POST /dweet/for/mkr1000?RPM="; data.concat(vRPM); // télécharger le moteur RPM data.concat("&Speed="); data.concat(vVitesse); // télécharger les données de vitesse de la voiture.concat("&Fuel="); data.concat(vFuel); // télécharger le niveau de carburant data.concat("&Temp="); data.concat(vTemp); // télécharger la température du liquide de refroidissement client.println(data); client.println("Hôte :https://www.dweet.io"); client.println("Connexion :fermer"); // fin de la connexion client.println(); } else { lcd.clear(); lcd.setCursor(0,0); lcd.println("La connexion a échoué"); }} 

Sur freeboard.io, nous devons créer un nouveau tableau de bord, et à l'intérieur de ce tableau de bord, créer une nouvelle source de données. Liez cette source de données à votre objet dweet.io que vous avez défini dans le code. Dans mon cas, c'est mkr1000. La création d'un nouveau widget Jauge que nous utiliserons pour afficher les données. Donnez-lui un nom et liez-le à l'une de nos variables. Ci-dessous, une capture d'écran de mon tableau de bord. Il indique la VITESSE, le RPM, le NIVEAU DE CARBURANT et la TEMPÉRATURE DU LIQUIDE DE REFROIDISSEMENT.

Conclusion

J'ai essayé les planches sur ma propre voiture, et cela fonctionne bien. Je travaille sur la conception d'un PCB qui inclut toutes les fonctions d'un circuit intégré. J'espère que j'écrirai d'autres tutoriels à l'avenir. Je peux également inclure une démo vidéo. Désolé cette fois, je n'ai pas pu prendre de vidéo ainsi que conduire ma voiture. Et vous devez également être prudent lorsque vous déboguez votre code en conduisant dans la rue !

La carte WiFi Arduino MKR est assez bonne pour cette application. Si j'ai plus de cartes, je pense que je pourrais essayer la carte MKR GSM 1400. N'hésitez pas à utiliser d'autres cartes IoT avec ce tutoriel et faites-moi part de vos commentaires.

Travailler sur le projet est amusant et éducatif. J'aime le sentiment de déboguer un problème. Il me fait aussi plaisir de partager ce que je sais sur le web. Merci pour la lecture. Faites-moi savoir si vous avez des questions ou des commentaires.

Code

  • IoT4Car_code
IoT4Car_codeC/C++
Ce programme parlera au véhicule à l'aide de la carte OBDII-UART, affichera les résultats sur l'écran LCD et téléchargera sur la plate-forme IoT Freeboard
/** OBDII-UART-Serial version 9 * Ce programme parlera au véhicule à l'aide de l'OBDII -Carte UART, * et afficher les résultats sur l'écran LCD, et télécharger sur la plate-forme IoT Freeboard* * Auteur :zhaoshentech* Mise à jour :2018-08-27* * mises à jour :* v3 :modification de la fonction getResponse() afin que le tampon reçoive la bonne réponse.* ajoutez le getRPM() pour obtenir le RPM du moteur du véhicule.* v4 :ajoutez la fonction getSpeed() pour obtenir la vitesse du véhicule* v5 :ajoutez le module LCD et affichez la vitesse et le RPM sur le LCD* v6 :est la version wifi* v7 :est la version non-wifi, non-série. Supprimez l'initialisation série,* afin que la carte puisse fonctionner sans ordinateur.* v8 :est la version non-wifi et non-série. Ajoutez le niveau de carburant et la température du liquide de refroidissement.* réorganisez l'emplacement d'affichage.* v9 :est la version wifi, non série. Vitesse maximale, régime, niveau de carburant et température du liquide de refroidissement* * Connexion du circuit LCD :* LCD broche RS à broche numérique 12* broche d'activation LCD à broche numérique 11* LCD broche D4 à broche numérique 5* LCD broche D5 à broche numérique 4* LCD Broche D6 à broche numérique 3 * broche LCD D7 à broche numérique 2* broche LCD R/W à la terre* Potentiomètre 10 K :* se termine à +5V et à la terre* essuie-glace à la broche LCD VO (broche 3)*///// ////////////////////////////////////////////////////////////// ////// Lié au WiFi //////////////////////////////////////// //////////////#include#includechar ssid[] ="VOTRE WIFI SSID" ; // wifi IDchar pass[] ="VOTRE WIFI PSWD"; // wifi passwordchar server[] ="www.dweet.io"; // freeboard et dweet Settingsunsigned long lastConnectionTime =0; // suivre la dernière connexion timeconst unsigned long postingInterval =10L * 1000L; // publier des données toutes les 10 secondesClient WiFi ; //Initialiser le wifi clientint status =WL_IDLE_STATUS; // l'état de la radio WiFi// inclut le LDC libaray#include const int rs =12, en =11, d4 =5, d5 =4, d6 =3, d7 =2;LiquidCrystal lcd(rs, en, d4, d5, d6, d7) ;// Ceci est un tampon de caractères qui stockera les données du port série:char rxData[20];char rxIndex =0;char inChar =0;String message;// Variables pour conserver la vitesse et les données RPM :int vSpeed ​​=0;int vRPM =0;int vFuel =0;int vTemp =0;void setup() { // Configurer le nombre de colonnes et de lignes de l'écran LCD :lcd.begin( 16,2) ; lcd.clear(); // vérifie la présence du shield :if (WiFi.status() ==WL_NO_SHIELD) { lcd.println("WiFi pas prêt"); tandis que (vrai); } // tentative de connexion au réseau WiFi :while (status !=WL_CONNECTED) { lcd.clear(); lcd.setCursor(0, 0); lcd.println("Connexion Wi-Fi..."); status =WiFi.begin(ssid, pass); // attend 5 secondes pour la connexion :delay(5000); } lcd.setCursor(0, 1); lcd.println("Connecté!"); // Serial1 est le port réel pour parler au véhicule Serial1.begin(9600); resetBuffer();}void loop() { while ( status !=WL_CONNECTED) { lcd.clear(); lcd.setCursor(0,0); // Se connecter au réseau Wi-Fi WPA/WPA2 Serial.println("Connexion au Wifi"); lcd.println("Connecter Wi-Fi..."); status =WiFi.begin(ssid, pass); // attend 10 secondes pour le délai de connexion (5000); } getVitesse(); getRPM(); getFuel(); getCoolTemp(); if (millis() - lastConnectionTime> postingInterval) { httpRequest(); lastConnectionTime =millis(); }}// getRPM data envoie la commande "010C" au port Serial1// et appelle getResponse() pour collecter les données. Ensuite, il imprime// les données RPM sur le Serial Monitor.void getRPM(void){ message ="010C"; Serial1.println(message); retard (200); //efface la ligne courante pour (int i =8; i <16; ++i) { lcd.setCursor(i, 0); // 0 ligne, i colonne lcd.write(' '); } lcd.setCursor(8,0) ; // première ligne seconde moitié de l'écran LCD // attendre la réponse getResponse(); // La réponse RPM divisée par 4 donne la valeur correcte. 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(message); retard (200); //efface la ligne courante :for (int i =0; i <8; ++i) { lcd.setCursor(i, 0); // 0 ligne, i colonne lcd.write(' '); } lcd.setCursor(0,0);// première ligne première moitié de l'écran LCD //attend la réponse de la voiture getResponse(); vVitesse =strtol(&rxData[6], 0, 16); // dans l'unité de km/h vVitesse =vVitesse * 0,621371; // dans l'unité de mph lcd.print(vSpeed); lcd.print(" mph");}void getFuel(void){ message ="012F"; Serial1.println(message); retard (200); // efface la ligne courante :for (int i =0; i <8; i++){ lcd.setCursor(i, 1); // 1ère ligne, i colonne lcd.write(' '); } lcd.setCursor(0, 1); // deuxième ligne première moitié de l'écran LCD //attend la réponse de la voiture getResponse(); vFuel =strtol(&rxData[6], 0, 16); // dans l'échelle de 255 //vFuel =244; // débogage de l'utilisation vFuel =1.0* vFuel / 255 * 100 ; // à l'échelle de 100 lcd.print(vFuel); lcd.print(" %"); //Série.println(vFuel); // déboguer l'utilisation}void getCoolTemp(void){ message ="0105" ; Serial1.println(message); retard (200); // efface la ligne courante :for (int i =8; i <16; i++){ lcd.setCursor(i, 1); // 1ère ligne, i colonne lcd.write(' '); } lcd.setCursor(8, 1); // deuxième ligne seconde moitié de l'écran LCD //attend la réponse de la voiture getResponse(); vTemp =strtol(&rxData[6], 0, 16); // dans l'unité de C mais décalé de 40 degrés vTemp =vTemp - 40; // offset de 0 lcd.print(vTemp); // affiche le degré C lcd.write(0xDF); lcd.print("C");}// La fonction getResponse collecte les données entrantes de l'UART dans le tampon rxData// et s'arrête lorsque la réponse est transférée. Une fois que la chaîne de retour chariot // est détectée, le tampon rxData est terminé par null (afin que nous puissions le traiter comme une chaîne) // et l'index rxData est réinitialisé à 0 afin que la chaîne suivante puisse être copiée.void getResponse(void ){ while(Serial1.available()> 0) { // Commencez par vérifier si nous avons reçu le caractère de fin de message ('\r'). if(Serial1.peek() =='\r'){ // atteint la fin du message, efface le tampon série inChar =Serial1.read(); rxData[rxIndex] ='\0'; // Réinitialise l'index du tampon pour que le caractère suivant revienne au début de la chaîne rxIndex =0; } // Si nous n'avons pas obtenu la fin du caractère du message, ajoutez simplement le nouveau caractère à la chaîne else{ // Obtenez le nouveau caractère du port série :inChar =Serial1.read(); // ajoute le nouveau caractère à la chaîne et augmente la variable d'index :rxData[rxIndex++] =inChar; } }}void resetBuffer(void){ for (int i =0; i <20; i++){ rxData[i] =0; }}void httpRequest() { client.stop(); // crée une chaîne de données à envoyer au franc-bord if (client.connect(server, 80)){ Serial.println("Connected"); Données de chaîne ="POST /dweet/for/mkr1000?RPM="; data.concat(vRPM); // télécharger le moteur RPM data.concat("&Speed="); data.concat(vVitesse); // télécharger les données de vitesse de la voiture.concat("&Fuel="); data.concat(vFuel); // télécharger le niveau de carburant data.concat("&Temp="); data.concat(vTemp); // télécharger la température du liquide de refroidissement client.println(data); client.println("Hôte :https://www.dweet.io"); client.println("Connexion :fermer"); // fin de la connexion client.println(); } else { lcd.clear(); lcd.setCursor(0,0); lcd.println("La connexion a échoué"); }}

Schémas

Connectez Arduino MKR WiFi 1000, carte SparkFun OBD-II UART, SparkFun Logic Level Shifter et LCD 1602 frizling_schematics_M8kF26dafQ.fzz

Processus de fabrication

  1. Plaque d'immatriculation
  2. Système de freinage antiblocage
  3. Qu'est-ce qu'un groupe motopropulseur ?
  4. Qu'est-ce qu'un alternateur ?
  5. Évitement d'obstacles à l'aide de l'intelligence artificielle
  6. Contrôleur de jeu Arduino
  7. Qu'est-ce qu'une masse de châssis ?
  8. Disposition du châssis d'un véhicule
  9. Comprendre le câblage du véhicule