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

Auto HUD - Voorruitweergave voor snelheid en kompas

Componenten en benodigdheden

Arduino Nano R3
× 1

Over dit project

Beschrijving:

Ik wilde het! Ik was jaloers op de grote auto van mijn vriend Taggi die op de voorruit de snelheid liet zien. Ik moest het hebben, ik moest het natuurlijk zelf maken!

Softwarestandpunt:

Het projecteren van het circuit was het moeilijkste en meest verwarrende deel van de aansluiting van de 7 segmenten displays op de BCD decoders omdat nummers "omgekeerd" zijn (gespiegeld).

Er zijn 3 knoppen :+ en - voor het verhogen/verlagen van de helderheid en S/H om te schakelen tussen Snelheid in km/u en Koers in graden; in het geval van Heading brandt ook de rode LED, dit betekent "graden" van het kompas (1-360°) bij beweging. Het is geen elektronisch kompas, het is een GPS en je moet bewegen om de juiste informatie te hebben over de richting waarin je beweegt. De helderheid wordt opgeslagen in EEPROM geheugen na een minuut. De helderheid wordt zowel op displays als op LED gewijzigd door middel van PWM-pinnen.

Een belangrijk onderdeel van de code is voor het verzamelen van gegevens van GPS, voornamelijk snelheid en richting, en deze uit elke NMEA-zin te halen. Zelfs bij het gebruik van String-klasse, meestal voor het manipuleren van seriële NMEA-zinnen, is de hele uitwerkingsstroom stabiel en solide; het gebruikt "serialEvent()" om één keer per seconde gegevens van GPS te ontvangen , roept dan "nmeaExtractData()" aan en tot slot controleert het het datapakket met "nmea0183_checksum() om zeker te zijn van de gegevensintegriteit. Als u een ander merk en model GPS gebruikt, zorg er dan voor dat de zinnen dezelfde structuur hebben of u moet hier enkele wijzigingen aanbrengen EM406A gebruikt bijvoorbeeld "$GPRMC" pakket-ID, BT220 gebruikt "$GNRMC" in plaats daarvan... slechts een kleine naamswijziging... Een handige link kan u helpen met checksum-test:https://nmeachecksum.eqth.net - Hier een voorbeeld van een volledige NMEA-zin, deze bevat:id, tijd, geldigheid, breedtegraad, lengtegraad, snelheid, ware koers, datum, variatie en controlesom.

$GNRMC, 095836.000, A, 4551.9676, N, 01328.7118, E, 2.09, 341.84, 280519,, *08

De schets voorziet in het één voor één inschakelen van de vergrendeling voor elke afzonderlijke BCD-decoder, het instellen van het codenummer op de binaire 4-bits bus, het uitschakelen van de vergrendeling, enzovoort wanneer de waarde verandert. Niet-beduidende nullen aan de linkerkant zijn blanco (niet weergegeven).

Voordat een nieuwe schets wordt geladen naar de MCU vergeet niet de trui te verwijderen :het is verbonden met de Rx-pin van Arduino en is tijdens het laden zeker in conflict met GPS Tx. Nadat de software is geladen, plaatst u de Jumper opnieuw om de normale functionaliteit te herstellen.

Onderdelenlijst:

  • 1 x MCU Arduino Nano
  • 3 x 5161 als displays met zeven segmenten, gemeenschappelijke kathode, rood
  • 1 x Beitian BN-220 seriële TTL GPS (1 Hz GNRMC-zinnen)
  • 1 x trui
  • 3 x knoppen (normaal open) + 3 x hoofdletters
  • 22 x 1/4W 220 ohm weerstanden
  • 1 x 3 mm LED, rood
  • 2 x 100n condensatoren
  • 3 x 14511 BCD-decoders + vergrendeling
  • 1 x USB "B" vrouwelijk
  • 1 x striplijn 2x mannelijke pinnen (voor jumper)
  • 1 x striplijn 4x mannelijke pinnen om 90° te buigen (voor GPS)
  • 1 x pigtail-kabel die GPS verbindt met 4 pinnen aan boord
  • 22 x striplijn mannelijke pinnen om twee PCB's in een stapel samen te voegen
  • 1 stuk dubbelzijdig plakband om GPS op PCB te plakken
  • 6 x gedraaide striplijn 5x vrouwelijke pinnen (voor displays)
  • 50 x koperen klinknagels van 0,6 mm
  • 8 x M3-schroeven
  • 4 x M3 vrouwelijke torens 20 mm hoog
  • 1 x plastic doos + omslag (kijk naar mijn 3D-bestanden die klaar zijn om te worden afgedrukt, hieronder)

PCB (printplaten):

Ik heb twee dubbelzijdige PCB's gebruikt om die reden worden ongeveer 50 klinknagels of pinnen gebruikt om routes voor hele circuits op te lossen. Er zijn ook 5 uitlijngaten eerst te maken. Op elke print heb ik deze 5 uitlijnpunten ontworpen. In de downloadsectie heb je alle PCB-bestanden, componenten en soldeervlakken, gespiegeld, om te downloaden en af ​​te drukken via een laserprinter op "gele" of "blauwe" vellen; deze keer heb ik de blauwe gebruikt, maar ook de gele zijn goed en de prijs is lager. Ik moet zeggen dat de blauwe vellen beter zijn... Denk er bij het afdrukken aan de tonerbesparingsinstellingen uit te schakelen, gebruik in plaats daarvan een resolutie van 1200 dpi voor een diep, echt zwart resultaat. Het toneroverdrachtsproces van magische vellen naar PCB wordt gemaakt door het gebruik van een heet strijkijzer... In het Net zijn er enkele tutorials die laten zien hoe een goede PCB te produceren maar onthoud deze belangrijke punten:maak het koper perfect schoon en borstel het koper lichtjes met een ruwe keukenspons, 5 minuten strijken, thermische waterschok, twee gezichten uitlijnen door middel van 5 gaten (ik gebruikte 5 pinnen op een groot wit LED-oppervlak om te zien gaten), bescherm het andere gezicht tijdens corrosieproces. Ook het printen van componenten maakt het project "professioneel" :-)

OPMERKINGEN: de foto's zijn genomen voor de allerlaatste versie, dit betekent dat een paar details anders kunnen zijn:d.w.z. de vreemde groene draad rond de PCB's in de definitieve versie verdwijnt, of de Jumper is verplaatst van PCB #1 naar PCB #2. U moet de GPS instellen op een snelheid van 9600 bps, alleen 1Hz GNRMC NMEA-zin; dit kan worden gedaan met behulp van zijn eigen installatiesoftware. Tot slot, voordat u de vrouwelijke USB-connector soldeert, plakt u er een klein stukje isolatietape onder om ongewenst contact met een koperen leiding te voorkomen, aan de componentzijde, net eronder.

Voor de eerste keer stroom geven, u zult ontdekken dat de cijfers "onleesbaar" zijn, omdat het is gemaakt om ze weerspiegeld op de voorruit (spiegel) te bekijken. Installeer het in de auto voorin de bestuurdersstoel , zoek een comfortabele plek en repareer deze. Ik raad aan om de USB-stroomkabel aan te sluiten na de contactstand zodat deze aan/uit gaat als de motor aan/uit staat. Dat is alles dames en heren!

Nieuws en verbeteringen:

  • 25.03.2021:om het project te voltooien heb ik twee 3D .STL-modellen voorbereid op deze link:https://grabcad.com/library/car-hud-1 waar u bestanden kunt downloaden met betrekking tot een gevormde doos en zijn afdekpaneel voor dit project om af te drukken via een 3D-printer.
  • 20.07.2021:het is beschikbaar als V2 (versie twee) van de software dat je samen met twee draden en één weerstand hoogte-informatie op het display hebt als duizend meter (d.w.z. 0,89 =890 m), druk gewoon nog een keer op de S/H-knop! Instructies:1) GPS instellen om ook $GNGGA nmea-zin uit te voeren via zijn eigen software; 2) verbreek de werkelijke verbinding tussen de d5 Arduino pwm-pin en de rest van het circuit, sluit deze aan op de decimale puntpin van het centrale display met een 220ohm-weerstand; 3) sluit de d13 Arduino digitale pin aan op het circuit waarop d5 was aangesloten; kijk naar enkele foto's hieronder; 4) installeer V2-schets op uw Arduino Nano.
  • 01.11.2021:versie V2.2 is klaar voor jou. Wat nieuw? Over hoogte (reeds aanwezig met V2) toont de hud de volledige waarde tot 999 m, vanaf 1000 m toont het waarden in duizend, d.w.z. 1,24 (1240 m) of 2,02 (2020 m). Ik heb een LDR-fotoweerstand GL5539, een 10kOhm-weerstand en 2 draden toegevoegd. Kijk naar de onderstaande afbeeldingen voor V2.2-mods en installeer V2.2-schets op uw Arduino. De LDR-sensor past de helderheid automatisch aan (3 niveaus) afhankelijk van het lichtniveau (dag, bewolkt of nacht). Knoppen (+) en (-) werken nog steeds om de helderheid handmatig te wijzigen, ze hebben prioriteit; om terug te keren naar automatisch houdt u de knoppen (+) en (-) een tijdje tegelijk ingedrukt. De interne EEPROM om het helderheidsniveau op te slaan wordt niet meer gebruikt. Laten we eerst V2-mods doen!

Als u rijdt, rijdt u gewoon. Rij veilig!

Code

  • Auto-HUD Arduino-schets
Auto-HUD Arduino-schetsArduino
/* Deze schets fungeert als autoruit HUD (head-up display), door Marco Zonca, 10/2020 Arduino Nano als CPU, GPS BT-220 nmea elke 1 sec, 3 x knoppen, 3 x zeven segment displays gemeenschappelijke kathode , 3 x 14511 BCD-latch-decoder, MPU EEPROM-geheugen (1 byte) en veel weerstanden; WAARSCHUWING:=======Voordat u de software bijwerkt, moet u de RX-pin op Arduino (TX van GPS) loskoppelen via de JUMPER*/#include #include String inputString ="";String nm_time ="00:00:00";String nm_validity ="V";String nm_latitude ="dd°mm.mmmm'N";String nm_longitude ="ddd°mm.mmmm'E";String nm_knots ="0.0 kn";float nmf_knots =0.0;float nmf_kmh =0.0;int nmi_kmh =0;String nm_truecourse ="360";float nmf_truecourse =360;String nm_date ="dd/mm/jjjj";int nmi_truecourse =0;byte kCent =0;byte kDeci =0;byte kUnit =0;byte tCent =0;byte tDeci =0;byte tEenheid =0;byte helderheid =120;byte latch_off =HOOG;byte latch_on =LAAG;int n=0;unsigned long lastmemcheck =0; unsigned long memcheck =60000; // vink aan om elke 60 seconden de "helderheidswaarde" in EEPROM op te slaan bool stringComplete =false; bool isKMH =true; bool ret =false; const int disp001 =2; // eenheden tonen latchconst int disp010 =8; // tientallen tonen latchconst int disp100 =12; // undreds display latchconst int disp001dim =9; // eenheden display dimmer/off pinconst int disp010dim =10; // tientallen display dimmer/off pinconst int disp100dim =11; // undreds display dimmer/off pinconst int button_kt =14; // kmh/truecourse buttonconst int button_more =15; // helderheid + buttonconst int button_less =16; // helderheid - buttonconst int gradenLED =3; // graden LEDconst int bit_3 =7; // bit 3const int bit_2 =6; // bit 2const int bit_1 =5; // bit 1const int bit_0 =4; // bit 0const int dly =10; // vertragingsvergrendeling m/seconde byte uit =0; // hetzelfde als helderheid =0const int addr =0; // EEPROM-adres voor helderheidswaardeconst-bytenummers [10] [4] ={{0,0,0,0},{1,0,0,0},{0,1,0,0},{1, 1,0,0},{0,0,1,0}, {1,0,1,0},{0,1,1,0},{1,1,1,0},{0, 0,0,1},{1,0,0,1}}; // bits 0,1,2,3void setup() {Serial.begin(9600); Draad.begin(); inputString.reserve(200); helderheid =EEPROM.lezen (addr); if (helderheid> 250 || helderheid <10) { helderheid=120; } // vermijd gekke waarden van 1e EEPROM lees pinMode (disp001, OUTPUT); pinMode (disp010, UITGANG); pinMode (disp100, UITGANG); pinMode (gradenLED, OUTPUT); pinMode(button_kt, INPUT_PULLUP); pinMode (button_less, INPUT_PULLUP); pinMode(button_more, INPUT_PULLUP); pinMode(bit_3, UITGANG); pinMode (bit_2, UITGANG); pinMode(bit_1, UITGANG); pinMode(bit_0, UITGANG); analogWrite(disp001dim, uit); // uit en nul geeft analogWrite weer (disp010dim, uit); analogWrite(disp100dim, uit); analogWrite (gradenLED, uit); setBusNr(0); digitalWrite(disp001, latch_on); digitalWrite(disp010, latch_on); digitalWrite(disp100, latch_on); vertraging (dly); digitalWrite(disp001, latch_off); digitalWrite(disp010, latch_off); digitalWrite(disp100, latch_off); analogWrite(disp001dim, helderheid); // op display analogWrite (disp010dim, helderheid); analogWrite (disp100dim, helderheid);} // setup () void loop () { // GPS NMEA ------------------ if (stringComplete ==true) { // ontvangen nmea-zin door seriële poort RX ret =nmeaExtractData(); invoerString =""; stringComplete =onwaar; if (ret ==true) { kCent=nmi_kmh/100; n=nmi_kmh-(kCent*100); kDeci=n/10; n=nmi_kmh-(kCent*100)-(kDeci*10); kEenheid=n; tCent=nmi_truecourse/100; n=nmi_truecourse-(tCent*100); tDeci=n/10; n=nmi_truecourse-(tCent*100)-(tDeci*10); tEenheid=n; Scherm(); } } if (millis()> (lastmemcheck+memcheck)) { // zet de helderheidswaarde in het geheugen (indien gewijzigd) EEPROM.update(addr,brightness); lastmemcheck=millis(); } checkButtons();}void display() {if (isKMH ==true) { // snelheid in km/h (isKMH=true) analogWrite (gradenLED, uit); setBusNr(kEenheid); digitalWrite(disp001, latch_on); vertraging (dly); digitalWrite(disp001, latch_off); if (kDeci> 0 || kCent> 0) { // zet tientallen uit if tientallen=0 (en ook undreds=0) setBusNr(kDeci); digitalWrite(disp010, latch_on); vertraging (dly); digitalWrite(disp010, latch_off); analogWrite(disp010dim, helderheid); } else { analogWrite(disp010dim, uit); } if (kCent> 0) {// zet undreds uit if=0 setBusNr(kCent); digitalWrite(disp100, latch_on); vertraging (dly); digitalWrite(disp100, latch_off); analogWrite(disp100dim, helderheid); } else { analogWrite(disp100dim, uit); } } else { // ware peiling in graden (isKMH=false) analogWrite (gradenLED, helderheid); setBusNr(tEenheid); digitalWrite(disp001, latch_on); vertraging (dly); digitalWrite(disp001, latch_off); if (tDeci> 0 || tCent> 0) {// zet tientallen uit if tientallen=0 (en ook undreds=0) setBusNr(tDeci); digitalWrite(disp010, latch_on); vertraging (dly); digitalWrite(disp010, latch_off); analogWrite(disp010dim, helderheid); } else { analogWrite(disp010dim, uit); } if (tCent> 0) { // zet undreds uit if=0 setBusNr(tCent); digitalWrite(disp100, latch_on); vertraging (dly); digitalWrite(disp100, latch_off); analogWrite(disp100dim, helderheid); } else { analogWrite(disp100dim, uit); } }} // display()void checkButtons(){ if (digitalRead(button_kt) ==LAAG) {if (isKMH ==true) { isKMH=false; } anders { isKMH=waar; } vertraging (250); } if (digitalRead(button_more) ==LAAG) {if (helderheid <=240) { helderheid=helderheid+10; } analogWrite(disp001dim, helderheid); analogWrite(disp010dim, helderheid); analogWrite(disp100dim, helderheid); vertraging (100); } if (digitalRead (button_less) ==LAAG) {if (helderheid>=20) { helderheid=helderheid-10; } analogWrite(disp001dim, helderheid); analogWrite(disp010dim, helderheid); analogWrite(disp100dim, helderheid); vertraging (100); }} // checkButtons () void setBusNr (int nummer) {// stelt 4 bits bus in voor (byte b=0; b<=3; b++) {if (numbers[number][b]==0) {if (b==0) {digitalWrite(bit_0, LOW);} if (b==1) {digitalWrite(bit_1, LOW);} if (b==2) {digitalWrite(bit_2, LOW);} if (b ==3) {digitalWrite(bit_3, LOW);} } else { if (b==0) {digitalWrite(bit_0, HIGH);} if (b==1) {digitalWrite(bit_1, HIGH);} if ( b==2) {digitalWrite(bit_2, HIGH);} if (b==3) {digitalWrite(bit_3, HIGH);} }}} // setBusNr()// gegevens extraheren uit nmea inputStringbool nmeaExtractData() {int d=0; int s=0; int y=0; int z=0; vlotter t=0; bool ret =onwaar; //true if nmea zin =$GNRMC en geldige CHKSUM if ((inputString.substring(0,6) =="$GNRMC") &&(inputString.substring(inputString.length()-4,inputString.length()- 2) ==nmea0183_checksum(inputString))) { y=0; for (s =1; s <11; s ++) { y=inputString.indexOf(",",y); switch (s) { case 1://-----------------------time z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_time=inputString.substring(y+1,y+2+1)+":"+inputString.substring(y+1+2,y+4+1)+" :"+inputString.substring(y+1+4,y+6+1); } y=z; pauze; geval 2://-----------------------validiteit z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_validity=inputString.substring(y+1,y+1+1); } y=z; pauze; geval 3://-----------------------breedtegraad z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_latitude=inputString.substring(y+1,y+2+1)+"°"+inputString.substring(y+1+2,y+10+1)+" '"; } y=z; pauze; geval 4://-----------------------noord/zuid z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_latitude=nm_latitude + inputString.substring(y+1,y+1+1); } y=z; pauze; geval 5://-----------------------lengtegraad z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_longitude=inputString.substring(y+1,y+3+1)+"°"+inputString.substring(y+1+3,y+11+1)+" '"; } y=z; pauze; geval 6://-----------------------oost/west z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_longitude=nm_longitude + inputString.substring(y+1,y+1+1); } y=z; pauze; geval 7://-----------------------snelheidsknopen z=inputString.indexOf(",",y+1); if (z>(y+1)) { nmf_knots=inputString.substring(y+1,z).toFloat(); t=roundOneDec(nmf_knots); nm_knots=String(t,1)+"kn"; nmf_kmh=roundTwoDec(nmf_knots * 1.852); nmi_kmh=roundZeroDec(nmf_knots * 1.852); } y=z; pauze; geval 8://-----------------------true course z=inputString.indexOf(",",y+1); if (z>(y+1)) { nmf_truecourse=inputString.substring(y+1,z).toFloat(); t=roundZeroDec(nmf_truecourse); nmi_truecourse=t; d=t; nm_truecourse=d; } y=z; pauze; geval 9://-----------------------datum z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_date=inputString.substring(y+1,y+2+1)+"/"+inputString.substring(y+1+2,y+4+1)+" /20"+inputString.substring(y+1+4,y+6+1); } y=z; pauze; casus 10:// verklaringen n.u. pauze; standaard:// statements n.u. pauze; } } ret=waar; } return ret;} // nmeaExtractData()/* SerialEvent vindt plaats wanneer er nieuwe gegevens binnenkomen in de hardware seriële RX. Deze routine wordt uitgevoerd tussen elke keer dat loop() wordt uitgevoerd, dus het gebruik van vertraging in de lus kan de reactie vertragen. Mogelijk zijn er meerdere bytes aan gegevens beschikbaar.*/void serialEvent() { while (Serial.available()) { char inChar =(char)Serial.read(); inputString +=inChar; // als het inkomende teken een nieuwe regel is, stel dan een vlag in zodat de hoofdlus // er iets aan kan doen if (inChar =='\n') { stringComplete =true; } }} // serialEvent()//bereken controlesom van nmea zinString nmea0183_checksum(String nmea_data) {int crc =0; String chSumString =""; int ik; // negeer het eerste $-teken, checksum in zin voor (i =1; i <(nmea_data.length()-5); i ++) { // verwijder de - 5 indien nee "*" + cksum + cr + lf aanwezig zijn crc ^=nmea_data[i]; } chSumString =String (crc,HEX); if (chSumString.length()==1) { chSumString="0"+chSumString.substring(0,1); } chSumString.toUpperCase(); return chSumString;} // nmea0183_checksum (String nmea_data)// round zero decimalsfloat roundZeroDec (float f) { float y, d; y =f*1; d =y - (int)y; y =(zwevend)(int)(f*1)/1; als (d>=0,5) { y +=1; } else { if (d <-0,5) { y -=1; } } return y;}// round one decimalfloat roundOneDec(float f) { float y, d; y =f*10; d =y - (int)y; y =(zwevend)(int)(f*10)/10; als (d>=0,5) { y +=0,1; } else { if (d <-0,5) { y -=0,1; } } return y;}// round two decimalsfloat roundTwoDec(float f) { float y, d; y =f*100; d =y - (int)y; y =(zwevend)(int)(f*100)/100; als (d>=0,5) { y +=0,01; } else { if (d <-0,5) { y -=0,01; } } retourneer y;}

Schema's

car-hud_m5RwPQqpxH.fzz ard-carhud-v2_3N5756haNI.ino ard-carhud-v2-2_XhXHFJu0T8.ino

Productieproces

  1. Sloop van een semi-autonome auto voor gehandicapte bestuurders
  2. Autonoom rijden AI voor vuilniswagen van ezels
  3. Realtime bewegingsplanning voor autonome auto's in meerdere situaties, onder gesimuleerde stedelijke omgeving
  4. Wat kan 5G opleveren voor de connected car?
  5. Veiligheid:een topprioriteit voor auto's van de toekomst
  6. Motorkabels voor aandrijvingen met variabele snelheid
  7. Verbeterde draaibanken voor polijsten en ontbramen
  8. Draaibank ontworpen voor precisie en snelheid
  9. Uitwisseling van productgegevens:een pijnpunt voor autofabrikanten
  10. Hoe kiest u een turbolader voor uw auto?
  11. Wat zijn de redenen voor olielekkage in mijn auto wanneer deze is ingepakt?