Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

IoT4Car

Componenten en benodigdheden

Arduino MKR1000
× 1
SparkFun Logic Level Converter - bidirectioneel
× 1
SparkFun OBD-II UART
× 1
SparkFun OBD-II naar DB9-kabel
× 1

Apps en online services

Arduino IDE
vrijboord
dweet

Over dit project

Achtergrond

Heeft u er tijdens het rijden met uw voertuig, een blik op uw dashboard, ooit aan gedacht om de meterstanden te verzamelen en een analyse te maken? Deze gegevens kunnen verborgen schatten bevatten. Voor individuen kan het uw rijgewoonten weerspiegelen, het kan u uw snelheid, uw gemiddelde mpg, het aantal verkeerslichten en uw wachttijd bij elk kruispunt vertellen. Voor bedrijven zijn deze gegevens van cruciaal belang voor realtime monitoring in wagenparkbeheer. De staat van het voertuig, de verdeling van de werklast, het brandstofverbruik en zelfs de locatie van het voertuig kunnen allemaal via de cloud worden teruggekoppeld naar een centraal besturingssysteem. Bedrijven kunnen machine learning gebruiken om de gegevens in een trainingsmodel te verwerken om de kosten te voorspellen en zelfs de kenmerken van de bestuurder te analyseren. Aangezien IoT wijdverbreid is, zullen de bovenstaande toepassingen niet ver weg zijn. Met de Arduino MKR-kaarten, gericht op IoT-toepassingen, kunt u zelf een apparaat bouwen dat met uw auto praat en telemetrische gegevens naar de cloud uploadt. Is dat niet cool?

Praten tegen een voertuig

We hebben een interface nodig om toegang te krijgen tot het voertuigsysteem. Waar kunnen we de auto hacken? Het antwoord is de OBD-II-interface.

Wat is OBD-II?

On-Board Diagnostics (OBD) is het ingebouwde zelfdiagnosesysteem van een voertuig waarmee we met onze auto's kunnen communiceren. Het werd voor het eerst geïntroduceerd in de Verenigde Staten in 1994 en werd een vereiste voor alle Amerikaanse voertuigen uit 1996 en nieuwer. Andere landen, waaronder Canada, delen van de Europese Unie, Japan, Australië en Brazilië hebben soortgelijke wetgeving aangenomen. OBD-II (tweede generatie) heeft vijf signaleringsprotocollen en Controller Area Network (CAN-bus) is daar één van. CAN-bus moet sinds 2008 in alle Amerikaanse auto's worden geïmplementeerd. Er is een geweldige introductie van OBDII door CSS Electronics op YouTube. In dit project krijgen we toegang tot gegevens via de 16-pins OBD-II-interfaces.

Mijn controller

Arduino is een uitstekend platform voor hobbyisten, makers en professionals. Het heeft een verscheidenheid aan borden die gericht zijn op verschillende toepassingen. Hier gebruik ik het Arduino MKR WiFi 1000-bord vanwege de wifi-mogelijkheid. Je kunt ook andere borden gebruiken die je leuk vindt. Ik zou Arduino MKR GSM 1400 aanraden, simpelweg omdat GSM veel grotere gebieden bestrijkt dan WiFi. Maar maak je geen zorgen, ook met wifi kunnen we langs de wegen internetten. Ik zal je de oplossing laten zien.

Het tolkbord

Hoewel Arduino zelf veel I/O's en talloze bibliotheken heeft, hebben we nog steeds een bord nodig dat OBD-protocollen kan vertalen in een taal die Arduino kan herkennen. Het bord dat ik gebruik is het SparkFun OBD-II UART-bord.

Met dit bord kunt u communiceren met de OBD-II-bus van uw auto. Het biedt u een seriële interface met behulp van de ELM327-opdrachtenset en ondersteunt alle belangrijke OBD-II-standaarden zoals CAN. Het bord bevat een STN1110-chip, een OBD-naar-UART-interpreter die kan worden gebruikt om berichten om te zetten tussen alle momenteel in gebruik zijnde OBD-II-protocollen en UART.

Er moet echter worden opgemerkt dat het interpreteerbord een I/O-spanning van 5 V heeft, wat de Arduino MKR-kaart I/O kan beschadigen als het rechtstreeks wordt aangesloten. Arduino MKR WiFI 1000 werkt op een lagere spanning en de I/O-spanning is 3,3 V. Daarom is een niveauverschuiver nodig om het signaal om te zetten van 5 V naar 3,3 V en omgekeerd. Hieronder staat de afbeelding van de niveauverschuiving die ik gebruik.

Sluit het aan

Het aansluiten van de schakeling is vrij eenvoudig. Sluit eenvoudig uw Arduino MRK-pin 13 Rx en pin 14 Tx aan op de OBD-II UART-kaart Tx- en Rx-pinnen via de niveauverschuiver. Natuurlijk moet je de grond van de twee planken met elkaar verbinden.

Om foutopsporing en demonstratie te vergemakkelijken, heb ik ook een LCD 1602-scherm op Arduino aangesloten om de gegevens in realtime weer te geven. De bedrading van LCD naar Arduino is te vinden in deze tutorial en zal hier dus niet worden uitgewerkt.

Hieronder ziet u de afbeelding van de breadboard-verbinding. De groene lijnen zijn voor de draden die de Arduino en het OBD-II UART-bord verbinden, terwijl de gele lijnen zijn voor de draden die de Arduino en het LCD-scherm verbinden. Het schema is ook beschikbaar in de bijlage.

De echte verbinding is een beetje rommelig vanwege het beperkte breadboard-oppervlak, maar het volgt het bovenstaande schema. Ik heb de micro-USB- en ODB-II-naar-DB9-kabel in de afbeelding opgenomen.

Serial1 niet serieel

Oké, het is tijd om ons Arduino MKR-bord te programmeren. Omdat mijn Arduino MKR-bord via UART met het interpreteerbord praat, is het niet nodig om bibliotheken van derden te installeren. Het verzenden van opdrachten naar het interpreteerbord is net zoiets als communiceren met Serial Monitor. Het enige dat ik wil benadrukken is dat de seriële poort die is gekoppeld aan Pin 13 en Pin 14 Seriële 1 is ! Arduino MKR-kaart Seriële poort verwijst naar de USB-poort die wordt gebruikt om met uw computer te communiceren. Vergeet niet te initialiserenSerial 1 poort in de setup() functie.

Serial1.begin(9600); 

En gebruik Serie 1 om het commando naar het tolkbord te pushen.

 Serial1.println(bericht); 

Berichten

Zoals je ziet, gebruik ik de variabele "message" om de commando's op te slaan. De OBD-commando's bestaan ​​uit hexadecimale codes geschreven in ASCII-tekens. De eerste twee hexadecimale getallen verwijzen naar de te gebruiken servicemodus. Er zijn 10 diagnostische services beschreven in de nieuwste OBD-II-standaard SAE J1979. Omdat we geïnteresseerd zijn in realtime monitoring, gebruiken we alleen 01 code om de huidige gegevens in dit project te tonen.

Elk hexadecimaal getal na de servicemodus vertegenwoordigt de parameter-ID (PID) om speciale functies te bereiken. Hieronder ziet u de schermafbeelding van de PID's in 01-servicemodus. Meer informatie is te vinden op Wikipedia.

In dit project zal ik laten zien hoe de autosnelheid, het motortoerental, het brandstofniveau en de motorkoelvloeistoftemperatuur kunnen worden verkregen. De OBD-commando's voor deze vier functies zijn:

  • 010D // autosnelheid
  • 010C // motortoerental
  • 012F // brandstofniveau
  • 0105 // koelvloeistoftemperatuur.

Decodeer de gegevens

Zodra de opdrachten zijn verzonden, luistert het Arduino MKR-bord naar de seriële 1-poort voor elk antwoord. Het is beter om een ​​vertraging van 200 ms in te stellen na het versturen van de commando's. Ik gebruik de volgende code om antwoord te krijgen.

void getResponse(void){ while(Serial1.available()> 0) { // Begin door te controleren of we het einde van het berichtteken ('\r') hebben ontvangen. if(Serial1.peek() =='\r'){ // bereik het einde van het bericht, wis de seriële buffer inChar =Serial1.read(); rxData[rxIndex] ='\0'; // Reset de bufferindex zodat het volgende teken teruggaat naar het begin van de string rxIndex =0; } // Als we het einde van het berichtteken niet hebben gekregen, voeg dan gewoon het nieuwe teken toe aan de tekenreeks else{ // Haal het nieuwe teken van de seriële poort:inChar =Serial1.read(); // voeg het nieuwe teken toe aan de string en verhoog de indexvariabele:rxData[rxIndex++] =inChar; } }} 

De reactie van het tolkbord volgt het formaat

">1 herhaalde PID-gegevens"

In de bovenstaande schermafbeelding stuur ik bijvoorbeeld "010D" om de snelheid van de auto te krijgen. Het antwoord is ">1 0D 00". De eerste 5 karakters geven aan dat de auto het commando ontvangt en de PID 0x0D herhaalt. De laatste twee cijfers retourneren de snelheidsgegevens 0x00.

Dan stuur ik "010C" om het motortoerental te krijgen, het antwoord ">1 0C" toont de bevestiging van het commando, de gegevens 0x098C is 4 keer de motortoerentalwaarde in hexadecimaal. 0x098C / 4 =611 dec, dus het motortoerental is 611 tpm.

Daarna stuur ik het commando "012F" om het brandstofniveau te krijgen, en ik krijg gegevens 0x1D. Het brandstofpeil wordt berekend als 0x1D / 255 * 100 =11% dec.

Het laatste commando is "0105", wat me de koelvloeistoftemperatuur 0x79 geeft. De werkelijke temperatuur is 0x79 - 40 =81 gradenC dec. Dan herhaalt de commandoreeks zich.

Zoals u kunt zien, heeft de antwoordregel spaties tussen twee hexadecimale cijfers en de eerste 5 cijfers zijn gewoon herhalingen van de opdrachten. Daarom beginnen de echte gegevens vanaf het 6e teken (eerste begint vanaf index 0).

Bij het programmeren en debuggen is een seriële monitor handig, maar als het op echte toepassing aankomt, is een LCD-scherm draagbaarder en voldoet het aan de IoT-stroomvereisten. Vervang eenvoudig de seriële monitor door een LCD-scherm, u kunt uw autogegevens in realtime volgen. Hieronder is de foto van het gebruik van het project in mijn eigen auto.

Cloud onze gegevens

Het voordeel van de Arduino MKR ten opzichte van UNO is de internettoegankelijkheid. Arduino MKR richt zich op IoT-toepassingen en zal industrieën intelligenter en meer verbindend maken. In de automobieltoepassingen is de MKR WiFi 1000 misschien niet het beste bord, aangezien het wifi-signaal zeldzaam is in een buitenomgeving, maar ik gebruik mijn mobiele telefoon als een persoonlijke hotspot, dus dat is geen probleem.

Er zijn veel andere cloudplatforms om de gegevens op te slaan, te bekijken en te verwerken. Je kunt kiezen wat je wilt. Ik zal dweet.io en freeboard.io als voorbeeld gebruiken. Dweet.io biedt een API waarnaar u gegevens kunt verzenden. Freeboard.io heeft handvatten om de dweet.io-gegevens te nemen en te visualiseren. Er zijn verschillende tutorials om dweet.io en freebboard.io in te stellen, dus ik zal er niet nogmaals op ingaan. Als u geïnteresseerd bent, zijn hier enkele voorbeelden, voorbeeld 1, voorbeeld 2.

De data push-code wordt hieronder getoond als een illustratie hoe dweet-commando's te maken.

void httpRequest() { client.stop(); // maak een datastring om naar freeboard te sturen if (client.connect(server, 80)){ Serial.println("Connected"); String data ="POST /dweet/for/mkr1000?RPM="; data.concat(vRPM); // upload engine RPM data.concat("&Speed="); data.concat(vSpeed); // upload autosnelheidsgegevens.concat("&Fuel="); data.concat(vFuel); // upload brandstofniveau data.concat("&Temp="); data.concat(vTemp); // upload koelvloeistoftemperatuur client.println(data); client.println("Host:https://www.dweet.io"); client.println("Verbinding:sluiten"); // einde van verbinding client.println(); } else { lcd.clear(); lcd.setCursor(0,0); lcd.println ("Verbinding mislukt"); }} 

Op freeboard.io moeten we een nieuw dashboard maken en binnen dit dashboard een nieuwe gegevensbron maken. Koppel deze gegevensbron aan uw dweet.io-ding dat u in de code hebt gedefinieerd. In mijn geval is dat mkr1000. Maak een nieuwe Meter-widget die we zullen gebruiken om de gegevens weer te geven. Geef het een naam en koppel het aan een van onze variabelen. Hieronder een screenshot van mijn dashboard. Het toont SNELHEID, RPM, BRANDSTOFNIVEAU en KOELVLOEISTOFTEMPERATUUR.

Conclusie

Ik heb de boards op mijn eigen auto geprobeerd en het werkt goed. Ik ben bezig met het ontwerpen van een printplaat die alle functies in een geïntegreerde schakeling omvat. Hopelijk zal ik in de toekomst meer tutorials schrijven. Ik kan ook een videodemo toevoegen. Sorry deze keer, ik kon niet zo goed video opnemen als autorijden. En u wilt ook voorzichtig zijn bij het debuggen van uw code terwijl u op straat rijdt!

Arduino MKR WiFi-bord is goed genoeg voor deze toepassing. Als ik meer borden heb, denk ik dat ik het MKR GSM 1400-bord kan proberen. Voel je vrij om andere IoT-borden te gebruiken met deze tutorial en vertel me je feedback.

Het werken aan het project is leuk en leerzaam. Ik geniet van het gevoel een probleem op te lossen. Het is mij ook een genoegen om wat ik weet op het web te delen. Bedankt voor het lezen. Laat het me weten als je vragen of opmerkingen hebt.

Code

  • IoT4Car_code
IoT4Car_codeC/C++
Dit programma praat met het voertuig via het OBDII-UART-bord, geeft de resultaten weer op het LCD-scherm en uploadt naar het vrijboord IoT-platform
/** OBDII-UART-serie versie 9* Dit programma praat met het voertuig via de OBDII -UART-bord, * en de resultaten weergeven op het LCD-scherm en uploaden naar vrijboord IoT-platform* * Auteur:zhaoshentech* Bijgewerkt:2018-08-27* * updates:* v3:de functie getResponse() gewijzigd zodat de buffer ontvangt het juiste antwoord.* voeg de getRPM() toe om het motortoerental van het voertuig te krijgen.* v4:voeg de getSpeed()-functie toe om de snelheid van het voertuig te krijgen* v5:voeg de LCD-module toe en toon de snelheid en RPM op de LCD* v6:is de wifi-versie* v7:is de niet-wifi, niet-seriële versie. Verwijder seriële initialisatie* zodat het bord zonder computer kan werken.* v8:is de niet-wifi, niet-seriële versie. Voeg brandstofniveau en koelvloeistoftemperatuur toe.* herschik de weergavelocatie.* v9:is de wifi, niet-seriële versie. Upolad-snelheid, toerental, brandstofpeil en koelvloeistoftemperatuur* * LCD-circuitverbinding:* LCD RS-pin naar digitale pin 12* LCD Schakel pin naar digitale pin in 11* LCD D4-pin naar digitale pin 5* LCD D5-pin naar digitale pin 4* LCD D6 pin naar digitale pin 3 * LCD D7 pin naar digitale pin 2* LCD R/W pin naar aarde* 10 K potentiaalmeter:* eindigt op +5V en aarde* wiper naar LCD VO pin (pin 3)*///// ////////////////////////////////////////////////// ////// WiFi gerelateerd ////////////////////////////////////////// ///////////////#include#includechar ssid[] ="UW WIFI SSID"; // wifi IDchar pass [] ="UW WIFI PSWD"; // wifi-wachtwoordchar-server [] ="www.dweet.io"; // vrijboord en dweet Settingsunsigned long lastConnectionTime =0; // volg de laatste verbinding timeconst unsigned long postingInterval =10L * 1000L; // post elke 10 seconden gegevensWiFiClient-client; // Initialiseer de wifi clientint-status =WL_IDLE_STATUS; // de WiFi-radiostatus// inclusief de 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);// Dit is een karakterbuffer waarin de gegevens van de seriële poort worden opgeslagen:char rxData[20];char rxIndex =0;char inChar =0;String-bericht;// Variabelen om de snelheid en de RPM-gegevens vast te houden:int vSpeed ​​=0;int vRPM =0;int vFuel =0;int vTemp =0;void setup() { // Stel het aantal kolommen en rijen van het LCD-scherm in:lcd.begin( 16,2); lcd.wissen(); // controleer de aanwezigheid van het schild:if (WiFi.status() ==WL_NO_SHIELD) { lcd.println("WiFi niet gereed"); terwijl (waar); } // probeer verbinding te maken met wifi-netwerk:while (status !=WL_CONNECTED) { lcd.clear(); lcd.setCursor(0, 0); lcd.println("WiFi verbinden..."); status =WiFi.begin(ssid, pass); // wacht 5 seconden op de verbinding:vertraging (5000); } lcd.setCursor(0, 1); lcd.println("Verbonden!"); // Serial1 is de directe poort om te praten met voertuig Serial1.begin (9600); resetBuffer();}void loop() { while (status!=WL_CONNECTED) { lcd.clear(); lcd.setCursor(0,0); // Maak verbinding met WPA/WPA2 wifi-netwerk Serial.println ("Verbinding maken met wifi"); lcd.println ("Verbind wifi..."); status =WiFi.begin(ssid, pass); // wacht 10 seconden op verbindingsvertraging (5000); } getSpeed(); getRPM(); getFuel(); getCoolTemp(); if (millis() - lastConnectionTime> postingInterval) { httpRequest(); lastConnectionTime =millis(); }}// getRPM data stuurt de opdracht "010C" naar de Serial1-poort// en roept getResponse() aan om de gegevens te verzamelen. Vervolgens drukt het// de RPM-gegevens af op de Serial Monitor.void getRPM(void){ message ="010C"; Serial1.println(bericht); vertraging (200); // wis de huidige regel voor (int i =8; i <16; ++i) { lcd.setCursor (i, 0); // 0 rij, ik kolom lcd.write (' '); } lcd.setCursor(8,0); // eerste rij tweede helft op het LCD-scherm // wait response getResponse(); // De RPM-respons gedeeld door 4 geeft de juiste waarde. 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(bericht); vertraging (200); // wis de huidige regel:for (int i =0; i <8; ++i) { lcd.setCursor (i, 0); // 0 rij, ik kolom lcd.write (' '); } lcd.setCursor(0,0);// eerste rij eerste helft in het LCD-scherm // wacht op het antwoord van de auto getResponse(); vSpeed ​​=strtol(&rxData[6], 0, 16); // in de eenheid van km/h vSpeed ​​=vSpeed ​​* 0.621371; // in de eenheid van mph lcd.print(vSpeed); lcd.print("mph");}void getFuel(void){ message ="012F"; Serial1.println(bericht); vertraging (200); // wis de huidige regel:for (int i =0; i <8; i++) { lcd.setCursor (i, 1); // 1e rij, ik kolom lcd.write(' '); } lcd.setCursor(0, 1); // tweede rij eerste helft op het LCD-scherm // wacht op het antwoord van de auto getResponse(); vFuel =strtol(&rxData[6], 0, 16); // in de schaal van 255 //vFuel =244; // debug gebruik vFuel =1.0* vFuel / 255 *100; // in de schaal van 100 lcd.print (vFuel); lcd.print(" %"); //Serial.println(vFuel); // gebruik debuggen} void getCoolTemp (void) { message ="0105"; Serial1.println(bericht); vertraging (200); // wis de huidige regel:for (int i =8; i <16; i++) { lcd.setCursor (i, 1); // 1e rij, ik kolom lcd.write(' '); } lcd.setCursor(8, 1); // tweede rij tweede helft in het LCD-scherm // wacht op het antwoord van de auto getResponse(); vTemp =strtol(&rxData[6], 0, 16); // in de eenheid van C maar verschoven met 40 graden vTemp =vTemp - 40; // gecompenseerd door 0 lcd.print (vTemp); // print de graad C lcd.write (0xDF); lcd.print("C");}// De getResponse-functie verzamelt binnenkomende gegevens van de UART in de rxData-buffer// en sluit af wanneer het antwoord is verzonden. Zodra de regelterugloop// is gedetecteerd, wordt de rxData-buffer op nul beëindigd (zodat we deze als een tekenreeks kunnen behandelen)// en wordt de rxData-index teruggezet naar 0 zodat de volgende tekenreeks kan worden gekopieerd.void getResponse(void ){ while(Serial1.available()> 0) { // Begin door te controleren of we het einde van het berichtteken ('\r') hebben ontvangen. if(Serial1.peek() =='\r'){ // bereik het einde van het bericht, wis de seriële buffer inChar =Serial1.read(); rxData[rxIndex] ='\0'; // Reset de bufferindex zodat het volgende teken teruggaat naar het begin van de string rxIndex =0; } // Als we het einde van het berichtteken niet hebben gekregen, voeg dan gewoon het nieuwe teken toe aan de tekenreeks else{ // Haal het nieuwe teken van de seriële poort:inChar =Serial1.read(); // voeg het nieuwe teken toe aan de string en verhoog de indexvariabele:rxData[rxIndex++] =inChar; } }}void resetBuffer(void){ for (int i =0; i <20; i++){ rxData[i] =0; }}nietig httpRequest() { client.stop(); // maak een datastring om naar freeboard te sturen if (client.connect(server, 80)){ Serial.println("Connected"); String data ="POST /dweet/for/mkr1000?RPM="; data.concat(vRPM); // upload engine RPM data.concat("&Speed="); data.concat(vSpeed); // upload autosnelheidsgegevens.concat("&Fuel="); data.concat(vFuel); // upload brandstofniveau data.concat("&Temp="); data.concat(vTemp); // upload koelvloeistoftemperatuur client.println(data); client.println("Host:https://www.dweet.io"); client.println("Verbinding:sluiten"); // einde van verbinding client.println(); } else { lcd.clear(); lcd.setCursor(0,0); lcd.println ("Verbinding mislukt"); }}

Schema's

Sluit Arduino MKR WiFi 1000, SparkFun OBD-II UART-kaart, SparkFun Logic Level Shifter en LCD 1602 aan frizling_schematics_M8kF26dafQ.fzz

Productieproces

  1. Kentekenplaat
  2. Antiblokkeerremsysteem
  3. Wat is een aandrijflijn?
  4. Wat is een dynamo?
  5. Obstakel vermijden met behulp van kunstmatige intelligentie
  6. Arduino-gamecontroller
  7. Cloud-kostuum
  8. Pixie:een op Arduino gebaseerd NeoPixel-polshorloge
  9. Wat is een chassisgrond?
  10. Chassisindeling van een voertuig
  11. Voertuigbedrading begrijpen