Introduction: Custom OBD II Gauge in With OEM Look
https://github.com/stirobot/arduinoModularTFTgaugesI built a custom OBD II (on board diagnostics version 2 http://en.wikipedia.org/wiki/On-board_diagnostics) gauge in the clock of my Subaru BRZ (GT86, FRS) and a lot of people wanted me to build them one. Here is how you can build one of your own. My wife is about to give birth to our second son and all the code is open source, so I have nothing to lose by posting this.
(I still may sell the installation as a service or possibly the packaging of a kit in the future, but that won't prevent others from using the open source pieces to do what they want in their own installations, other cars, other displays, etc. and frankly there is no money to be had in this. So, I'd rather share it with the DIY community at large.)
I'll try to point out where I did things that are specific to my model of car and where you might want to change things to suit your needs. Hopefully this will allow others to build on what I've done.
The all important github link:https://github.com/stirobot/arduinoModularTFTgauge...
And more generically my code is here: https://github.com/stirobot/arduinoModularTFTgauges
The car specific forum where all of this is getting discussed: http://www.ft86club.com/forums/showthread.php?p=1967204#post1967204
Step 1: What You Will Need to Do This (parts/tools/software/etc)
-An Arduino or Arduino clone – I specifically use the adafruit pro-trinket for its small form factor and 5v logic.https://www.adafruit.com/products/2000
-STN1110/ELM327 board. I chose the Sparkfun one because it is stable, uses UART for communication and doesn't cost and arm and a leg. https://www.sparkfun.com/products/9555
-Assorted hookup wire
-128x32 SPI monochrome OLED display. I used the adafruit one. The ebay ones may work just as well, but I haven't tested them.
-Your OEM clock. I used the OEM clock from a Scion FRS that I got on ebay.
-Some resistors (for the button setup)
-Optional – sensors (autometer oil temp, autometer oil pressure, acceleromter, pressure, temperature). I have some arduino code that will let you plug analog sensors into a system like this. I'll make one of the “steps” pages about this.
Code libraries used:
-Arduino ELM327 library: https://www.clusterfsck.io/blog/2014/05/23/arduino-elm327-library/ . I thrashed around with the UART comms to the OBD II board for a long time. (you can see it in my crummy code for the 1.8” TFT version of this). This saved my project and my sanity.
-The Adafruit libraries for the OLED screen and tutorials: https://learn.adafruit.com/monochrome-oled-breakouts I love supporting this vendor as they always provide a lot of extras when you buy from them (support, working code (emphasis on working), tutorials, etc.)
Sublime Text2 Stino plugin (because real syntax highlighting is refreshing) - http://robot-will.github.io/Stino/
the dot factory – for making monochrome bitmaps into arrays so you can display them on the screen (That's how I got my icons)
windows paint – for drawing icons and splash screens
Step 2: Choosing Your Screen
I've been through several projects like this in the past and I have some advice to share on selecting a screen.
-You want the screen to fit in the OEM location with as little modification to the car as possible. I ended up measuring everything and cutting out templates on paper to see what would fit. For an old project similar to this I used a standard 16x2 character LCD. It fit perfectly in the GD Impreza's clock location (https://code.google.com/p/robotmeter/)
-You want as much support as you can get in terms of a graphics API. The adafruit stuff is awesome. Their TFT and OLED graphics API's are great.
-You want the best visibility in all lighting conditions. Cars see night, day and direct sunlight to all their displays. OLED screens are great at this. Transflective LCD's are also good at this. Reflective and Transmissive LCD's are not good at all.
-Polarized sunglasses can sometimes ruin a great design if their polarization lines up the wrong way with the screen you select. Test things out before you dive into coding.
Step 3: Reuse Code From the Community
I reused the wonderful ELM327 library from David Irvine (https://www.clusterfsck.io/blog/2014/05/23/arduino-elm327-library/) and it saved me a lot of headache. Please reuse my code as it might save you some time or at least give you some ideas.
Graphics API's are great, but what's better is looking at the code that uses them. Look at other projects that employ the API you are using and see how they deal with things like screen flicker, drawing bar charts, scatter plotting, etc.
Step 4: (if You Are Using My Code or Making Your Own) Find the Vehicle Specific CAN Codes for Your ECU
Finding the vehicle specific CAN codes for your vehicle can give you much more info than the generic OBD II PID's. In my case the BRZ/FRS/GT86 community has discovered two important codes which show data that you would otherwise not be able to get from these cars via the standard OBD II PID.
For my car these included oil temperature (very important for track/autocross driving) and fuel remaining.
I had to modify/use the David Irvine API to use the Oil Temp PID. For a lot of applications (and for mine), this was a two part process. First you have to express a CAN header and then ask for the PID like you normally would. I added this code to the ELM327 initialization code:
runCommand("AT SH 7E0",data,20); //(FRS/gt86/brz specific CAN header)
Then I queried for the oil temp:
(I added my own function to the ELM327 class for this.)
So, the hard part is finding what these are for you car. The easiest places to look are:
-The Torque android app forums
-The vehicle specific forums for your make/model of car (I found that this is especially true of a lot of the diesel truck models).
-The Scangauge X-gauge PID library (http://www.scangauge.com/support/x-gauge-commands/)
-And, finally if you can't find what you are looking for you can do some CAN sniffing of your own (which there are other instructables on: https://www.instructables.com/id/CAN-Bus-Sniffing-and-Broadcasting-with-Arduino/ )
After you find the correct PID the next part is picking out the data out of the (sometimes long) string of characters returned. Getting this position correct is sometimes a pain and requires a lot of debugging and possibly a specific arduino sketch where you guess and check positions until you get close. Another approach is to spam the responses to the serial monitor (an arduino mega is helpful here) then graphing them in a spreadsheet to figure out which hex number (converted to decimal) changes with the specific sensor reading you are interested in. You may also want to check this against the ground truth of an actual sensor or a known good OBD II program like the torque app.
Step 5: Disassemble Your Clock
-Find the car make/model specific forum of your choice and find the DIY section to find out how to get the clock out without breaking anything. Be especially careful if the clock shares a PCB with something critical (in my instance the airbag status lights and hazard button are on the same PCB). Sometimes a DIY which describes how to change the color of the clock (popular modification in a lot of cars) will come in handy.
-De-solder (https://www.instructables.com/id/How-To-Desoldering/) the clock or cut it out entirely (depends on your specific car). I have included pictures of what I did to mine for reference.
-On my car this included removing back-lighting LEDS as well.
Step 5: Reusing clock buttons
I was lucky in this regard. My OEM clock has three buttons. I was able to reuse them to control the screen. I assigned them these functions H=high, show the peak measure; M=mode, switch display pages; 00=reset the peak readings.
In order to reuse the buttons I had to remove them from their curcuit and wire them up to a circuit like this: http://tronixstuff.com/2011/01/11/tutorial-using-analog-input-for-multiple-buttons/ .
I ended up pulling them off of the circuit board with pliers and then using electrical tape as insulation. This is far from ideal. The better way to do it is to follow this instructable: https://www.instructables.com/id/Solder-on-PCB-traces/ . Use and exact knife to clear out traces around the one you are interested in.
If you aren't lucky and don't have buttons to reuse, buy some spst buttons of your liking and mount them wherever you'd like. I suggest using ones the come in a screw casing so you can drill a hole and mount them neatly.
Step 6: Test Everything Out Before Taking Everything Apart
(yes this is out of order)
This should probably go without saying, but test everything out before you wire it in permanently and before you hack up your clock.
Step 7: A Word About Power Savings
The ST chip used in the OBD II UART device has some excellent power save features. I use the one which puts the chip to sleep when it is not getting power to the UART pins. This allows me to keep everything semi-permanently installed without worrying about it draining the battery. Specifically I make use of this command in the initialization to put it in this mode:
runCommand("STSLU", data, 20); //sleep on UART inactivity and wake on activity
There a whole host of other power save options that you can read about here: http://www.scantool.net/downloads/79/stn11xx-powe... I have yet to test this with a multimeter, but will soon (and hopefully remember to update this page).
Step 8: Wire Up and Power Up
This is the fritzing diagram of how I have everything plugged in for reference. I did it with the more common arduino form factor instead of the Adafruit Trinket that I am actually using at the moment. Hopefully this will make things more clear for some people.
Step 9: Innovate!
The world is your oyster here. Things I suggest changing or customizing:
-What is displayed on each page. What OBD II readings you are interested in.
-Find CAN specific PID's for your car and use those.
-Change the button config to only use one button and use long holds to reset things or display highs.
-Scale to a 128x64 OLED or other larger screen.
-Reuse some of my sensor code found in this project to add off the shelf gauge senders/accelerometer/etc to your project: https://code.google.com/p/robotmeter/
-Fork my code. Publish what you've made (here on instructables and elsewhere).