Arduino Forum

Community => Exhibition / Gallery => Topic started by: Power_Broker on Feb 26, 2019, 12:12 am

Title: Car Heads Up Display
Post by: Power_Broker on Feb 26, 2019, 12:12 am


Link to final(ish) YouTube vid: link (https://www.youtube.com/watch?v=JxBvukUipc4)



Hello everyone!

This thread is going to be the ongoing build/development log for my next side project; an Arduino based car diagnostics and Heads Up Display (HUD) tool.

Some years ago I had the chance to drive a C6 Corvette with a HUD and loved it! The ability to see your speed and RPM without taking your eyes off the road was amazing. For a long, long time I've wanted to make a HUD for my own car. While doing some research about OBD2 and CAN bus interfacing I figured I might as well have a user interface for actual diagnostics in addition to the HUD - all in one package.

To get started developing this project I've decided to use the following parts:
- 1 Teensy 3.5                                                                    --- Controller
- 1 Waveshare SN65HVD230 CAN Transceiver         --- Signal Converter
- 1 iKKEGOL OBD-II Male Extension Cable (pigtail)  --- Car/Transceiver Interface Cable
- 1 Diymall 0.95" Blue and Yellow I2C OLED Screen --- Diagnostics Screen
- Assorted pushbuttons/switches                               --- User Interface Control

Once I get things working well enough, I'll add a higher power LED display for the HUD and a custom made PCD for final assembly. I will also make a 3D printed enclosure for the device.
Title: Re: Car Diagnostics and HUD Tool
Post by: detown on Feb 26, 2019, 06:21 pm
Looks like a cool project. As another gear head, looking forward to your progress.
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Mar 08, 2019, 01:15 am
I received all the components for my initial prototype and began soldering today.

Things are looking good so far but I may have some trouble with the OLED screen. Looks like DIYMall (the vendor) has a different hardware setup than the normal Adafruit OLED screen. This means an edited version of the Adafruit OLED library must be used and is provided by DIYMall. The other problem is that I'm using the Teensy's I2C bus Wire1 which is not the normal I2C port used in the OLED library. This unfortunately means I'm going to have to edit the library to get it to work.

Lastly, I'll start to test the OBDII connector pin positions and the CAN transceiver module after I get the OLED screen working.



BTW, I forgot to mention that I'm using an adjustable buck converter as a 12V -> 5V DC power supply. The 12V will come from the OBDII 12V pin. I'm also using two 4.7K Ohm resistors for the I2C pullups.
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Mar 09, 2019, 11:05 pm
Tested the OLED screen and it looks like it's a dud. I was able to initialize it using the DIYMall libraries, but I could only get random pixels to light and they would never turn off after initialization, oof.

I decided to get one of these (https://www.amazon.com/gp/product/B0711RKXB5/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) instead. I opted for this specific type because it got rave reviews and it should work with the normal Adafruit OLED screen library.

I also decided to add a fuse for the +12V power coming from the car. Instead of getting a normal car fuse, I opted for a 2A fast blow fuse and got some 5x20mm fuse PCB mounts. Here are the links: fuses (https://www.amazon.com/gp/product/B004HM2FUA/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1), fuse mounts (https://www.amazon.com/gp/product/B074N1NMMX/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1).

Today I also did some testing on my OBDII extension cable. First, I looked up the pinout of the car-side OBDII connector:


From the pinout I noticed I only cared about 5 of the 16 pins:
- +12V
- Chassis Ground
- Signal Ground
- CAN High
- CAN Low

Next I looked at my OBDII extension plug's pin labeling, found the pin numbers I cared about, and used the multimeter to find which wire corresponded to which pin. Once I identified each pin, I labeled it using tape and a marker.







Lastly, I was randomly looking around google and I found something I might be able to use for the project. Turns out people sometimes use what is called a scope lens protector for their gun sights. It's a small piece of glass or see-through plastic that sits on a rail mount in front of a gun sight. I might be able to use one of these for the HUD part of the project. Here's what I'm talking about:




ToDo:
- Connect the plug to my car's OBDII port and test the connections
- Test the new OLED
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Mar 12, 2019, 02:23 am
Yesterday I got the new OLED screen and it works flawlessly with my Teensy.

Today the 2A fast blow fuses and their mounts came in today. Turns out the mounts don't quite fit a standard PCB hole pattern, so I soldered them inline with the wires from the OBDII cable, hot glued the mounts together, and then soldered a 4 position JST female connector on the end.

I then took it out to the car and tested the connections with my multimeter. First I verified that I was getting +12V from the power wires. Then I verified that there is ~60 Ohms resistance across the CANH and CANL lines (since there are two 120 Ohm terminating resistors in parallel on the CAN line - total resistance should be 60 Ohms). Looks like the wiring of the cable is good!

I also did some reading on Chassis GND vs Signal GND and decided there was no real need to use Signal GND. Because of this, I'm only using Chassis GND as my ground - Signal GND isn't being wired for this project.

Here are some pics:




Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Mar 12, 2019, 02:24 am
Sorry that the pics are lopsided, they're right side up on my computer lol
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Mar 12, 2019, 03:33 am
I found a cool 3D printable HUD setup I might edit and use for this project: HUD Link (https://www.thingiverse.com/thing:2459191)
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Mar 13, 2019, 11:33 pm
Did some research on the FlexCAN library that gets installed with teensyduino: although I could be wrong, it looks like it only runs on a T3.6, but there was a header comment in one of the libraries files that said it worked with all of the Teensys. Then I stumbled upon a PJRC forum thread that said something about some FlexCAN library versions working with the T3.5 and some that don't so I decided to just ask on the PJRC forum about it.

So far I have one reply from tonton81 about a library he wrote that is an improved version of the FlexCAN library and works for the T3.5. I plan on testing that library out soon.


I also did some hardware testing today. I hauled out my oscilloscope to my car and hooked it up to the CANH and CANL lines with my car "on". TBH I was just looking to see if there were CAN packet waveforms showing up on the o-scope and not necessarily any data in particular. The reason for this test was because a research team for the University of Tulsa tried to get diagnostics data off of a dodge using the OBD CAN bus. They apparently couldn't do it due to the dodge's CAN bus being present but inactive. Since I have a dodge, I wanted to make sure my CAN bus is active. I'd hate to put in such effort for an impossible project lol.

Check this (http://tucrrc.utulsa.edu/DodgeCAN.html) out for more info.

Turns out - IT WORKS! My CAN bus is active. Now I just have to get the data onto my Teensy.






Title: Re: Car Diagnostics and HUD Tool
Post by: GaryP on Mar 14, 2019, 09:41 am
All this information you give makes me just more confused, but I like this project.


Are these signals and data streams standardized on some level, after all those OBD-adapters I have bought, seems like they have specialized for some brand, VAG is the easiest, my 2006 BMW is not.

Can't wait to see how you get all this together! Nice work so far!
 :)

Cheers,
Kari
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Mar 14, 2019, 10:49 pm
Thanks Kari!

The OBD connector shape is standardized. The pinout is partially standardized - not completely, but partially. The standardized pins (for vehicles in the USA post 2008) are the pins called out in the pinout pic in post #3.

My apologies for being confusing - this is a learning experience for me too.
Title: Re: Car Diagnostics and HUD Tool
Post by: GaryP on Mar 15, 2019, 06:29 am
My apologies for being confusing - this is a learning experience for me too.
No no, you are not, you are parsing and analyzing things nicely, it's the information behind that makes me puzzled. My learning curve is getting harder every year.

I really would love the HUD speed on my windscreen, without only the support from GPS. Combination of both of them, OBD and GPS, maybe even helps to calculate estimate tyre wearing (is that a correct word?) at the same time.

Cheers,
Kari

Title: Re: Car Diagnostics and HUD Tool
Post by: Bringamosa on Mar 24, 2019, 08:33 am
Following too btw :)
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on Apr 27, 2019, 02:14 am
Soooo, today I uploaded an example of the Improved FlexCan Library and connected it to my car. It reset some things in the diagnostics computer and lit the check engine light. Fortunately, the check engine light cleared itself after about 20min or so, but it spooked me enough to switch to a COTS (Commercial Off the Shelf) approach.

I found a cool website (https://theksmith.com/software/hack-vehicle-bus-cheap-easy-part-1/) that explains the basics of interfacing with COTS OBD2 to Bluetooth adapters. I plan on connecting to one of those modules with an HC-05 and moving on with the project from there.
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on May 02, 2019, 03:40 am
I ordered one of these (https://www.amazon.com/gp/product/B005NLQAHS/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1) bad boys as my OBD-II interface. It is an ELM327-based OBD-II scanner with bluetooth compatibility. This device connects to the car's physical OBD port and reports car data over bluetooth. You also configure the device over bluetooth using custom AT commands (https://www.sparkfun.com/datasheets/Widgets/ELM327_AT_Commands.pdf).



I plugged it into my car, was able to connect to it with my laptop and send it AT commands over bluetooth. I was also able to monitor vehicle speed (in km/h) and engine RPM with the following commands and their responses:

To set up protocol --> AT SP 0
Response                 --> OK

To query vehicle speed --> 010D
Response                         --> 41 0D <data>

To query engine RPM --> 010C
Response                      --> 41 0C <data>

This website (https://www.obdsol.com/knowledgebase/obd-software-development/reading-real-time-data/) explains in better detail what the above commands do and how to interpret the responses.


I was also able to connect to the OBD scanner with my HC-05 bluetooth module. I wasn't able to successfully send commands with my HC-05, but that battle will be waged another day...
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on May 03, 2019, 01:53 am
I was able to use the following demo code to quickly get my HC-05 talking with the ELM327:


Code: [Select]

// 1D,A5,1F16BB

//#define ATMODE 1

void setup()
{
  Serial.begin(115200);
  while(!Serial);

#ifdef ATMODE
  Serial2.begin(38400);
#else
  Serial2.begin(115200);
#endif

  while(!Serial2);
  Serial2.println("AT SP 0");
}

void loop()
{
  byte c;

 #ifdef ATMODE
  if(Serial.available())
  {
    c = Serial.read();
    Serial.write(c);
    Serial2.write(c);
  }

  if(Serial2.available())
  {
    c = Serial2.read();
    Serial.write(c);
  }
#else
  Serial2.println("010C");
  
  while(Serial2.available())
  {
    c = Serial2.read();
    Serial.write(c);
  }
  delay(100);
#endif
}



With line #3 uncommented, I entered the following commands after putting the HC-05 into AT mode:

- AT
- AT+UART=115200,0,0
- AT+CMODE=0
- AT+ROLE=1
- AT+RESET
- AT+INQM=0,5,9
- AT+INIT
- AT+INQ
(discovered the address of the OBD-II scanner is 1D:A5:1F16BB - yours might be different)
- AT+PAIR=1D,A5,1F16BB,20
- AT+BIND=1D,A5,1F16BB
- AT+LINK=1D,A5,1F16BB
- AT+RESET

Next, I uncommented line #3 and then reuploaded the code. Once the updated code was uploaded, it spat out raw dataframes at about 10Hz!
Title: Re: Car Diagnostics and HUD Tool
Post by: Power_Broker on May 13, 2019, 11:52 pm
In order to make interfacing with the OBD scanner as easy as possible, I wrote a library for it: ELMduino GitHub (https://github.com/PowerBroker2/ELMduino)

Here is an example sketch I ran today with my own hardware to get RPM data at ~13Hz:
Code: [Select]

#include <ELMduino.h>

ELM327 myELM327;

float rpm;
uint64_t currentTime = millis();
uint64_t previousTime = currentTime;
uint16_t samplePeriod = 80;

void setup()
{
  Serial.begin(115200);
  Serial3.begin(115200);
 
  delay(2000);
 
  if(!myELM327.begin(Serial3))
    Serial.println("Couldn't connect to ELM327");

  if(!myELM327.queryRPM(rpm))
  {
    Serial.println("\tTimeout");
  }
  else
    Serial.print("RPM: "); Serial.println(rpm);
}

void loop()
{
  currentTime = millis();
  if((currentTime - previousTime) >= samplePeriod)
  {
    previousTime = currentTime;
   
    if(!myELM327.queryRPM(rpm))
    {
      Serial.println("\tTimeout");
    }
    else
      Serial.print("RPM: "); Serial.println(rpm);
  }
}



NOTE: This will only work if you have already paired your HC bluetooth board with the OBD scanner. Otherwise, it works like a charm!


Next I'm going to add queries in the test sketch for vehicle speed in addition to the already existing queries for RPM.

Title: Re: Car Heads Up Display
Post by: Power_Broker on May 15, 2019, 12:37 am
Got speed and rpm data working together with some updates to the library and the test sketch. Here's the sketch:

Code: [Select]

#include <ELMduino.h>




ELM327 myELM327;

enum fsm{
  get_speed,
  get_rpm};
fsm state = get_rpm;

float rpm;
float speed_kmph;
float speed_mph;
uint64_t currentTime = millis();
uint64_t previousTime = currentTime;
uint16_t samplePeriod = 100;




void setup()
{
  Serial.begin(115200);
  Serial3.begin(115200);
 
  delay(2000);

  myELM327.begin(Serial3);
}




void loop()
{
  currentTime = millis();
  if((currentTime - previousTime) >= samplePeriod)
  {
    previousTime = currentTime;

    switch(state)
    {
      case get_rpm:
        if(myELM327.queryRPM(rpm))
        {
          updateLEDs();
        }
        else
          Serial.println("\tTimeout");
        state = get_speed;
        break;
       
      case get_speed:
        if(myELM327.querySpeed(speed_kmph))
        {
          speed_mph = speed_kmph * 0.621371;
          updateLEDs();
        }
        else
          Serial.println("\tTimeout");
        state = get_rpm;
        break;
    }
  }
}




void updateLEDs()
{
  Serial.print(rpm); Serial.print(" "); Serial.println(speed_mph);
 
  return;
}


Next step is to get this all working with the LED display.
Title: Re: Car Heads Up Display
Post by: Power_Broker on May 30, 2019, 11:14 pm
I designed a PCB for the project!

I'll be using a Teensy 3.5, HC-05, 75 ohm LED current limiting resistors, 2 7-segment LED displays, and a 10-segment LED display.

Here are some pics of the design (gerber files are attached):



Title: Re: Car Heads Up Display
Post by: Power_Broker on Jun 07, 2019, 07:51 pm
@sandracarmona

Unfortunately, I'm not fluent in Spanish. Google translate has your message as:
Quote
In the high range, more and more smartphones have opted for OLED technology for their screens. We have clear examples in the LG V30, the Galaxy Note 8, the Pixel 2 XL and more recently, the iPhone X, the last one to join this list.

Having an OLED screen allows for more striking designs where the screen is clear protagonist. But are they all advantages? We talk about what we earn but we also lose with OLED screens in our phones
Is this correct?

If so, I'm not sure what your point is. I'm not currently interested in using an OLED display for the HUD. This is because I'll be able to make the LED display brighter than an OLED one. Also, I'm trying to keep this project, so a few 7/10-segment displays are all I need.

Using an OLED display might be a next step development once the initial prototype is complete...maybe.

Did you have any specific questions about this project?
Title: Re: Car Heads Up Display
Post by: Power_Broker on Jul 01, 2019, 02:30 am
Updated the library and the sketch code since my last update.

Library link: https://github.com/PowerBroker2/ELMduino (https://github.com/PowerBroker2/ELMduino)
Sketch code: https://github.com/PowerBroker2/ELMduino/blob/master/examples/ELMduino_Test/ELMduino_Test.ino (https://github.com/PowerBroker2/ELMduino/blob/master/examples/ELMduino_Test/ELMduino_Test.ino)


I also discovered a hardware bug in the PCB design. Basically, I forgot to wire one of the LED control pins to the Arduino. Because of this, I had to solder a flyaway between the two pins. Here's a pic of the job:



Here are some pics of the final hardware product:






Once I get the enclosure designed and everything working, I'll post some videos!


Title: Re: Car Heads Up Display
Post by: Power_Broker on Jul 04, 2019, 04:19 am
Attached is a loose parts list for the project so far (does not include SPI breakout connector).
Title: Re: Car Heads Up Display
Post by: Power_Broker on Jul 12, 2019, 03:41 am
Today I finished printing a mount/enclosure for the HUD and tested it in a parking lot. Here's a video of the test:

https://www.youtube.com/watch?v=D_ITHF5Tr0I (https://www.youtube.com/watch?v=D_ITHF5Tr0I)
Title: Re: Car Heads Up Display
Post by: Power_Broker on Jul 12, 2019, 03:45 am
Ok, how in the world do you embed youtube vids in posts?
Title: Re: Car Heads Up Display
Post by: GaryP on Jul 12, 2019, 09:40 pm
I am still following actively! This is just great! My projects lasts for years,I don't have anything to share, followers would die for natural causes before my projects ends...

Cheers,
Kari
Title: Re: Car Heads Up Display
Post by: jimLee on Aug 21, 2019, 10:46 am
Ok, this is cooler than all get out! Something I've been wanting to do for a while now.

I've vaguely following this. You tried to use the built in CAN bus stuff from the teensy but backed away and went with the blue tooth thing? Am I getting this right? If so why did you back away from using the teensy? Maybe I'm wrong because I see you have on on your PC board.

I use Teesnys for pretty much all my projects. I see the CAN bus stuff on there and always wanted to try it out.

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Aug 21, 2019, 08:29 pm
Ok, this is cooler than all get out! Something I've been wanting to do for a while now.
Coming from someone who designed an all-out Arduino Cell phone, this is high praise; thank you!!!

I've vaguely following this. You tried to use the built in CAN bus stuff from the teensy but backed away and went with the blue tooth thing? Am I getting this right? If so why did you back away from using the teensy? Maybe I'm wrong because I see you have on on your PC board.
Almost correct.

I did originally try to access the CAN port directly via the Teensy (plus CAN transcievers), but after accidentally resetting my car's diagnostics computer two or three times I decided to use the COTS bluetooth OBDII device. Since implementing the bluetooth device, I have yet to have a problem with it like I did when directly using the CAN port.

I still, though, use the Teensy to interface with the bluetooth device and drive the LED displays.


All in all, I've found the documentation on how to hook-up, interface, and (ESPECIALLY) develop code for the Teensy's CAN ports to be vague and nearly non-existant. I did find a CAN library for my T3.5, but the library code mixed with a lack of direction on how to use it caused my car's diagnostics computer to reset when using one of the example sketches (and that's pretty scary when it happens in your Charger R/T  :) ).

If someone were to do an in-depth look at how Teensy <--> Automotive CAN works and create a super comprehensive tutorial, I'd be interested in trying it out again ( ;) )
Title: Re: Car Heads Up Display
Post by: jimLee on Aug 22, 2019, 09:21 am
Coming from someone who designed an all-out Arduino Cell phone, this is high praise; thank you!!!
Wow thanks! I'd actually gotten the feeling that very few even noticed. I was amazed at how little the feedback was on that. And none whatsoever when I did the RPN calculator.

Anyway, my issue is that, although I know CAN bus is used as a little network in cars, I know nothing about it works or how they are using it. Id' have to get to grips with, er.. the "theory" of CAN bus first. Heck, I don't even know the voltage levels.

What's going on is that, I just bought this little 1999 Miata.  It was a cheap thrasher and the last couple owners had been trying to make a race car out of it. Racing stripes, big tires, loud, roll-bars, attracts police like flies to.. Well.. The issue is that right now I have no Speedo or Tach. and really no way to debug where the problem is. So it would be really nice to be able to see what the heck is buzzing around on its little CAN bus. Is there any Tach or Speed packets on the bus? Or is it the instrument cluster that's broken? Things like that.

Also, it would be totally cool to build a little HUD for the thing.

But I have to get my current project finished up before digging into it. (Way over designed plant watering system.)

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Nov 18, 2019, 12:07 am
Big update:

Finally sat down and finished updating the code for this project. Till now, I had some issues with syncing to the ELM327 and keeping sync. With this new update, I immediately sync up to the ELM327 and stay synced. I'm also getting ~3.5 Hz refresh rate for RPM and Speed (mph).

Here's a link to the updated library. (https://github.com/PowerBroker2/ELMduino) I'm going to put in a request for this library to be added to the Arduino IDE's Libraries Manager tonight, so look for it in your IDE in a week or so!


Hopefully I can get around to posting a video of it working soon...



Title: Re: Car Heads Up Display
Post by: Power_Broker on Nov 21, 2019, 03:56 am
Here is a video of the HUD in operation! (https://youtu.be/mBhZGMhq2SM)
Title: Re: Car Heads Up Display
Post by: Power_Broker on Feb 07, 2020, 04:11 am
Been a while since I've given an update, but currently I bought an ESP32 and have decided use it in this project. Specifically, I'm going to replace the Teensy 3.5/HC-05 combo with the new ESP32 since it has built-in bluetooth and WiFi capabilities.

With this change, I the project needs an updated library, sketch, and PCB design. I've already updated the ELMduino library (https://github.com/PowerBroker2/ELMduino) to be compatible with the ESP32 and am almost finished with the new PCB design - details to follow. Work on the sketch, however, will take some time considering the new feature I plan to implement: a diagnostics webpage. I can use the ESP32's WiFi capabilities to setup an "access point" for my phone to connect to. Then, the ESP will serve a webpage that contains diagnostics and telemetry information about my car (realtime).

More updates soon!
Title: Re: Car Heads Up Display
Post by: Power_Broker on Feb 08, 2020, 06:07 am
Here are the details/gerber files for the updated PCB design:




Title: Re: Car Heads Up Display
Post by: GaryP on Feb 09, 2020, 06:48 am
Idea of the circuit is nice, but that limits us using mph only, with km/h we would need three digits.

Well, the core of your design probably is easy to change to use other displaying methods.

Cheers,
kari
Title: Re: Car Heads Up Display
Post by: Power_Broker on Feb 17, 2020, 04:19 am
True, I don't plan on going over 99mph or driving in kph, but it shouldn't bee too hard to add a new LED display. If you use an ESP32, you might run out of pins, but then again, maybe not.

Also, I tested some recent updates to ELMduino (https://github.com/PowerBroker2/ELMduino) and verified everything still works! Looks like max throughput of the ELM327 is 13 total queries per second. This means, if I'm querying for both speed and rpm, I should expect a sample rate of about 6.5Hz - not bad! :D

I also was able to setup a *very* simple Access Point webserver with dynamic content (AJAX).

Currently printing the new HUD enclosure - pics soon!
Title: Re: Car Heads Up Display
Post by: Power_Broker on Feb 18, 2020, 01:16 am
Turns out that you can't use all pins on the ESP32 for digital IO. Because of that, I need to add another MCU to the board for LED driving and SPI communication. I decided to pair up the Teensy I had on the old HUD PCB with the ESP on the new PCB.

Attached are the pics and gerber files




Title: Re: Car Heads Up Display
Post by: Power_Broker on Feb 18, 2020, 04:05 am
And attached are the .obj files for 3D printing
Title: Re: Car Heads Up Display
Post by: jimLee on Feb 19, 2020, 06:21 am
If you're really getting fussy about digits, units etc. Just replace it with an OLED and have at it showing whatever you like.

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Feb 19, 2020, 04:51 pm
True, but is an OLED screen as bright as LEDs at full power? I'm concerned I won't be able to see the OLED screen on a sunny day
Title: Re: Car Heads Up Display
Post by: GaryP on Feb 19, 2020, 05:28 pm
OLEDs are typically small, so LED displays are nicer. Of course there is plenty of substitutes
for this design, so everyone should find suitable for them purposes.

I like to use TM1638s.

Cheers,
Kari
Title: Re: Car Heads Up Display
Post by: jimLee on Feb 20, 2020, 12:31 am
It wouldn't be as bright. And, sadly, OLEDs have limited lifespan. But, if they turned out to be bright enough, it could look really cool for awhile. Kinda' like the ones on the Chevy Camaros, where you get a color tach seemingly floating over the hood of the car.

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Mar 04, 2020, 10:41 pm
Update: Because I didn't realize some of the LED control wires were routed to non-digital pins on the Teensy (DAC0 and DAC1) as well as one LED control wire to D13, I had to revise the PCB design and order another set. The new PCBs should get here tomorrow or Friday.

I also added the ability to connect a color OLED screen to the PCB that will be controlled via the Teensy.

Attached are the PCB gerber files.




Title: Re: Car Heads Up Display
Post by: Power_Broker on Mar 04, 2020, 10:58 pm
Also, I made some massive improvements in the ELMduino.h library (https://github.com/PowerBroker2/ELMduino)!

Now you can use the library for custom PID queries in addition to standard queries. I also listed all available AT commands in the header.
Title: Re: Car Heads Up Display
Post by: jimLee on Mar 05, 2020, 02:44 am
I know one person's library may not be useful to anyone else, but.. If you would like a library that supports drawing to your OLED. And other things if you so desire. I have one you could try.

Actually, there's an entire multi-sketch swapping OS in there. But maybe save that for later?

The folder to look at first is LC_Screen
The library folder (https://github.com/leftCoast/Arduino/tree/master/libraries)

I'm currently working on the wiki for all this nonsense.

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Mar 05, 2020, 03:42 am
Very impressive collection of libraries! I'll be honest, I don't know where to start...

For now I'm only going to display speed, rpm, and ELM327 errors on the OLED. At some point it might be nice to have the capability for a menu system at some point to check/clear car error codes. Does one of you libs support easy menu making?

Currently, though, I plan on checking error codes via the ESP32's access point webserver on my phone/laptop (among other cool things).
Title: Re: Car Heads Up Display
Post by: jimLee on Mar 05, 2020, 05:01 am
Easy, no.. But the bases are there. You can do a list of things and have them lined up. The place to start is LC_baseTools. Everything is built on them. Even if you use nothing else, they are a really handy set of things to have around for doing Arduino code.

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Mar 07, 2020, 09:16 pm

Got the new code/PCB to work! (https://youtu.be/JxBvukUipc4)



Link to sketch code, PCB files, and 3D print files (https://github.com/PowerBroker2/ArduHUD)



Title: Re: Car Heads Up Display
Post by: Power_Broker on Mar 07, 2020, 09:21 pm
Images:







Title: Re: Car Heads Up Display
Post by: jimLee on Mar 08, 2020, 05:04 am
Pretty cool! Looks like its getting elaborate. You have plans for permeant packaging and mounting?

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Mar 08, 2020, 05:18 am
Thanks!

Probably won't make it much more permanent.
Title: Re: Car Heads Up Display
Post by: av4625 on Apr 20, 2020, 12:09 am
Awesome thread! I can confirm that this library is very easy to use and required very little thinking for me to get RPM data! Thanks! and thanks for your help on my question thread!

I seem to be able to get RPM data at 7-8Hz, I saw you talking about 13Hz. Would that speed difference just be down to your ELM327 and mine? Mine is just a cheap blue stubby ebay one.

I recall seeing information somewhere that says you shouldn't poll OBD more than 10 times a second as it causes buffer overflow in the ECU and that is potentially very bad I guess lol. Theres a linux OBD library and they won't let you poll more than that. This limitation is on cars before a certain year. I must try and find this information again, I found it back at the very start of messing with my project.
Title: Re: Car Heads Up Display
Post by: Power_Broker on Apr 20, 2020, 01:47 am
Awesome thread! I can confirm that this library is very easy to use and required very little thinking for me to get RPM data! Thanks! and thanks for your help on my question thread!
Thanks! Always glad to help!


I seem to be able to get RPM data at 7-8Hz, I saw you talking about 13Hz. Would that speed difference just be down to your ELM327 and mine? Mine is just a cheap blue stubby ebay one.
Pretty much all ELM327 modules under $40 are el-cheapo China devices. The one I got was probably not much more than $10.

Yeah, I get about 13Hz for repeatedly querying a single value (i.e. rpm). If I add more query values (i.e. poll both speed and rpm), the refresh rate for each value type goes down. Because of this, if you poll speed and rpm, you will get ~13/2Hz = ~7Hz refresh rate for each value type. Why your results are different, I'm not sure.


I recall seeing information somewhere that says you shouldn't poll OBD more than 10 times a second as it causes buffer overflow in the ECU and that is potentially very bad I guess lol. Theres a linux OBD library and they won't let you poll more than that. This limitation is on cars before a certain year. I must try and find this information again, I found it back at the very start of messing with my project.
My library doesn't allow you to re-poll the ELM327 until it's returned a response for the current poll - this allows you to poll the device as fast as possible. This is one of the reasons the library is blocking.


Title: Re: Car Heads Up Display
Post by: Power_Broker on Apr 21, 2020, 06:32 am
I updated the software a couple of weeks ago that allow SD card datalogging on the Teensy along with a very, very basic command line style interface. Basically, you can connect to the Teensy via USB while the HUD is running, type "ls" and it will list all of the "drive files" (a new "drive file" is created upon startup to store that drive's data). You can then enter the complete filename of the "drive file" you would like to analyze and the Teensy will do a complete datadump of the file.

I then wrote a Python program that, with the help of command line arguments, can use this interface to analyze and plot a test dataset, a dataset from a file system, or a dataset downloaded from the HUD directly over USB.

Here is the Python:
Code: [Select]
import os
import serial
import serial.tools.list_ports
import argparse
import pandas as pd
import matplotlib.pyplot as plt


SCRIPT_PATH   = os.path.realpath(__file__)
SCRIPT_DIR    = os.path.dirname(SCRIPT_PATH)
SER_DATA_DIR  = os.path.join(SCRIPT_DIR, 'ser_data')
SER_DATA_PATH = os.path.join(SER_DATA_DIR, 'ser_data.txt')
TEST_FILE_NUM = 1
TEST_FILE     = os.path.join(SCRIPT_DIR, 'test_data', 'drive_{}.txt'.format(TEST_FILE_NUM))


plot_list = []


class InvalidSerialPort(Exception):
    pass


def setup_args():
    parser = argparse.ArgumentParser()

    parser.add_argument('--td',   help='Use test data file')
    parser.add_argument('--ser',  help='Use serial interface to download data from the HUD')
    parser.add_argument('--port', help='Serial port to communicate with HUD')
    parser.add_argument('--baud', help='Serial baud to communicate with HUD')
    parser.add_argument('--dn',   help='Drive number - used with serial download only')
    parser.add_argument('--file', help='URL to file with data to be processed')
   
    return parser.parse_args()


def serial_ports():
    return [p.device for p in serial.tools.list_ports.comports(include_links=True)]


def plot_data(data_file, plot_title='Drive Data'):
    df = pd.read_csv(data_file)
    df.plot(subplots=True, figsize=(8, 8), x='Epoch', title=plot_title)
    plt.legend(loc='best')
    plot_list.append(plt)

def display_plots():
    for plot in plot_list:
        plot.show()

def conn_to_ser():
    port_name = None
   
    for p in serial_ports():
        if p == args.port or os.path.split(p)[-1] == args.port:
            port_name = p
            break

    if port_name is None:
        raise InvalidSerialPort('Invalid serial port specified.\
            Valid options are {ports},  but {port} was provided'.format(
            **{'ports': serial_ports(), 'port': args.port}))
    else:
        connection = serial.Serial()
        connection.port = port_name
        connection.baudrate = int(args.baud)
        connection.open()
       
        print('Connected on {}'.format(port_name))
   
    return connection

def drives_from_ser(connection):
    connection.write('ls\n'.encode())
                   
    while b'?' in connection.readline():
        connection.write('ls\n'.encode())
       
    drive_files = []
   
    while connection.in_waiting:
        try:
            line = connection.readline().decode('utf-8')
            print(' '.join(line.split()))
           
            if ('.txt' in line) or ('.csv' in line):
                drive_files.append(line.split()[0])
        except UnicodeDecodeError:
            pass
   
    return drive_files

def grab_ser_data(connection, drive):
    connection.write(drive.encode())
   
    while b'?' in connection.readline():
        connection.write(drive.encode())
   
    data_lines = []
   
    while True:
        line = connection.readline()
       
        if (b'-' * 50) in line:
            break
       
        elif (b'.txt' not in line) and (b'.csv' not in line):
            data_lines.append(line)
   
    return data_lines

def log_ser_data(connection):
    with open(SER_DATA_PATH, 'w') as ser_data:
        for data_line in data_lines:
            write_line = ''
           
            for char in data_line:
                if chr(char).isascii():
                    write_line += chr(char)
           
            if write_line.count(',') == 5:
                ser_data.write(write_line.strip())
                ser_data.write('\n')


if __name__ == '__main__':
    args = setup_args()

    if args.ser:
        if args.ser.lower() == 'true':
            if args.port and args.baud:
                try:
                    connection = conn_to_ser()
                    drive_files = drives_from_ser(connection)
                   
                    print(drive_files)
                   
                    if not os.path.exists(SER_DATA_DIR):
                        os.makedirs(SER_DATA_DIR)
                   
                    if args.dn:
                        drive_number = int(args.dn)
                        drive = 'drive_{}.txt'.format(drive_number)
                       
                        if drive in drive_files:
                            print(drive)
                           
                            data_lines = grab_ser_data(connection, drive)
                            log_ser_data(connection)
                           
                            if os.path.exists(SER_DATA_PATH):
                                try:
                                    plot_data(SER_DATA_PATH, drive)
                                except pd.errors.ParserError:
                                    pass
                                except TypeError:
                                    pass
                                except pd.errors.EmptyDataError:
                                    print('ERROR - Empty text file')
                               
                                display_plots()
                            else:
                                print('ERROR - Could not find file {}'.format(SER_DATA_PATH))
                        else:
                            print('ERROR - Drive file {} not found on SD'.format(drive))
                       
                    else:
                        for drive in drive_files:
                            print(drive)
                           
                            data_lines = grab_ser_data(connection, drive)
                            log_ser_data(connection)
                           
                            if os.path.exists(SER_DATA_PATH):
                                try:
                                    plot_data(SER_DATA_PATH, drive)
                                except pd.errors.ParserError:
                                    pass
                                except TypeError:
                                    pass
                                except pd.errors.EmptyDataError:
                                    print('ERROR - Empty text file')
                            else:
                                print('ERROR - Could not find file {}'.format(SER_DATA_PATH))
                       
                        display_plots()
                except:
                    import traceback
                    traceback.print_exc()
                   
                    data_file = TEST_FILE
            else:
                data_file = TEST_FILE
    elif args.file:
        if os.path.exists(args.file):
            try:
                plot_data(args.file)
                display_plots()
            except pd.errors.ParserError:
                pass
            except TypeError:
                pass
            except pd.errors.EmptyDataError:
                print('ERROR - Empty text file')
        else:
            print('ERROR - Could not find file {}'.format(args.file))
    elif args.td:
        data_file = TEST_FILE
    else:
        data_file = TEST_FILE
   
    try:
        if os.path.exists(data_file):
            try:
                plot_data(data_file)
                display_plots()
            except pd.errors.ParserError:
                pass
            except TypeError:
                pass
            except pd.errors.EmptyDataError:
                print('ERROR - Empty text file')
        else:
            print('ERROR - Could not find file {}'.format(data_file))
    except NameError:
        pass
   
    try:
        connection.close()
    except:
        pass



And here is an example dataset plotted by Python:



For the complete code of all pieces of the project, see the repo (https://github.com/PowerBroker2/ArduHUD).



Title: Re: Car Heads Up Display
Post by: jimLee on Apr 21, 2020, 08:09 pm
Why does the RPM look so jaggy? I'd think it would be pretty smooth, just like speed.

-jim lee
Title: Re: Car Heads Up Display
Post by: Power_Broker on Apr 21, 2020, 09:31 pm
I honestly don't know. I'd be curious to see what the RPM curves are like for other cars.
Title: Re: Car Heads Up Display
Post by: av4625 on Apr 24, 2020, 08:20 pm
Why does the RPM look so jaggy? I'd think it would be pretty smooth, just like speed.

-jim lee
I'd expect the RPM to look jaggy like that. For example, see where the car gets up to the higher speed and then stays at that high speed for a bit? The engine revs up to accelerate to the speed and then it drops into a higher gear when up to speed meaning the RPM comes down. I guess the slower bits are like junctions etc and here you would be reving up to accelerate and then braking and doing this over and over making it jaggy.
Title: Re: Car Heads Up Display
Post by: HM78 on Jun 05, 2020, 10:04 am
Hi, congratz for project.

I can't understand how you can connect to ELM327. It gives me 'connected' on serial monitor but it isn´t because i can't get values from it and BT led isn't on. I have the same elm327 BT that you showed (black with orange and blue tag).

On webpage from your last example you put in here, it didn´t show if its connected or not (i think).
Can you explain better how to check connection?

I have only the ESP32 as circuit hardware. Do i need something more?

When connect by Android i can connect to elm327 and get values in "torque" or "car scanner" but not with esp32.

I have read that using BT and Wifi at same time, ESP32 can be hot, confused or get burned.

Hoping for your answer,
Hugo Morais
Title: Re: Car Heads Up Display
Post by: Power_Broker on Jun 14, 2020, 05:37 am
1.) Post your code and schematic
2.) Ensure that your car is on and running
3.) Ensure that all other devices in the area have bluetooth turned off
4.) Ensure your ELM327's name is "OBDII", if not, change the name in the sketch or simply use the MAC address
5.) Try using 38400 baud instead of 115200
6.) Attempt connection manually with this sketch (https://github.com/PowerBroker2/ELMduino/blob/master/examples/ESP32_test/ESP32_test.ino). Try the following commands:
Quote
AT Z
AT E0
AT S0
AT SP0
010C
Title: Re: Car Heads Up Display
Post by: PGTMR2 on Sep 07, 2020, 06:10 am
Maybe the RPM is so spiky because the RPM is coming from the number 1 spark plug, not crank or cam position.
Title: Re: Car Heads Up Display
Post by: Power_Broker on Sep 07, 2020, 08:15 am
Yeah, and also consider this is for a ~15 minute drive, so the x axis is super condensed - plus having a large displacement engine with high revs doesn't help, lol
Title: Re: Car Heads Up Display
Post by: PGTMR2 on Sep 11, 2020, 09:45 am
The hood looks kind of Charger-ish, dash bezels too. But "high revving" makes me think Coyote Mustang. I love high rpms. Mostly 5,6, 10 and 12 cylinders for the insane sound. But I can appreciate V8's, Flat-plane crank followed by cross plane in preference.
Title: Re: Car Heads Up Display
Post by: Power_Broker on Sep 11, 2020, 06:30 pm
The hood looks kind of Charger-ish, dash bezels too.
Yeah, it's a Charger R/T 5.7L. Maybe not as high revs as a Coyote Mustang, but def higher than most cars
Title: Re: Car Heads Up Display
Post by: PGTMR2 on Sep 12, 2020, 07:48 am
No judgement, just the process of figuring out the car. 94 Ford Probe GT KLZE swap, ECU swap. I shift at 7k for spirited driving. Painting it right now. Should be driving it again soon.