Introduction: Tachometer/Scan Gauge Using Arduino, OBD2, and CAN Bus
Any Toyota Prius (or other hybrid/special vehicle) owners will know that their dashboards may be missing a few dials! My prius has no engine RPM or temperature gauge. If you are a performance guy, you may want to know things like timing advance and fuel data in real time. If you're a hypermiler, you may want to know more information about your fuel economy.
All these values are calculated by your car's engine computer. It simply takes a scan tool to read the data. Many curious car owners turn to commercial solutions such as a Scan Gauge. They may also use a scantool that uses ELM327 over USB or Bluetooth. Popular contenders are the Carista, BlueDriver, or a regular ol Innova/Bosch diagnostic scan tool.
I wanted to have a permanent installation in my vehicle with dedicated hardware, so I decided to go my own route! I am excited to share my custom scan tool design.
- Arduino board (can use Nano, Teensy, Pro Micro, Uno....) [Amazon]
- Fuse tap+extra fuse (Make sure you have the right size) [auto parts store]
- OBD II connector (I salvaged one from an old scan tool) [Amazon]
- CAN Bus MCP2515 module [Amazon]
- OLED Display (or other display of choice) [Amazon]
- Buck converter (or other switching / linear voltage regulator) [Amazon]
- 4-conductor cable for your display (use old USB cable, ribbon cable, etc.)
- Plenty of jumper wires for connecting everything
- Soldering equipment
- Wire strippers
- 3D printer (or access to one) to create the following parts:
- Enclosure for arduino
- Screen bezel/dashboard mount
Step 1: About the CAN Bus (and Disclaimer)
YOU ARE OPENING A SERIOUS CAN OF WORMS HERE...
Messing around with your vehicle/can bus can cause damage and/or unintentional operation of your vehicle! I am providing this code and instruction to you with no warranty or guarantee. You assume all risk. Try this while the vehicle is PARKED FIRST! This project is actually fairly safe if you simply do a little research about what you are doing. If you don't know what any part of the instructions or code means, it's probably a sign that you should not be messing with your car's electrical system! Don't take this project on. Buy a premade bluetooth OBD dongle and use that instead. I wish you good luck.
Now that the disclaimer is out of the way..does CAN sound familiar? Maybe similar to LAN (Ethernet) , or WLAN (WiFi) that you may have at home...that's because they are all networks. CAN stands for Controller Area Network. It's a digital communications platform that your car uses to talk to itself. Instead of running wires from the engine computer to each sensor, light, and device in your car, they are all digitally controlled over the network.
The CAN bus is a differential communication protocol. That means that it only needs two wires! There is no Tx/Rx like you might find in traditional Serial communications, and no direct transmission between two devices. It is typically found as a twisted pair throughout your vehicle. You will be accessing it through the OBD port. You don't necessarily need to understand how this protocol works at the fundamental level, but you must understand it enough to be able to write or modify the Arduino code.
If you want to follow this project, make sure your vehicle has a CAN bus! Almost every vehicle on the road today has an OBD II port. They all have the same electrical connector under the dashboard. However, there are wildly differing protocols for communication based on your auto manufacturer. Any vehicle sold in the United States after 2008 uses ISO 15765 CAN bus. That is what we want to use for this project. Check to make sure your vehicle has a CAN bus. Keep in mind that every car is unique. You will have a specific CAN bus speed, certain OBD codes that you must request, and miscellaneous quirks that you must mitigate along the way.
Step 2: Wiring Diagram
Now is the time to start planning out your enclosure and installation. My car has a fuse box in the hood and one right under the dash. Where is yours? Time to start thinking.
I used a fuse tap on the windshield wiper circuit since my Prius has many circuits fused right next to the OBD port. You can use the Vbatt on the OBD port, but beware! That is hooked to the battery, so the device will never turn off. Bad idea. Depending on the current draw of the Arduino, it may kill your battery in a matter of days or weeks if you let your car sit! If you are using an OLED display, you may experience excessive burn-in if your device is on all the time. It's very important that the device is switched to your ignition.
You may have an easy solution! You may have a vehicle with an ACC/ignition power pin on the OBD port. Lots of pins are manufacturer specific. That means that your OBD port may have a power pin that is switched to ignition. However, don't just try the multimeter and hook your arduino up to anything with 12 volts! Your vehicle may have a J1699 or other serial bus that uses 12v logic level. Who knows what a current draw would do! Check with oscilliscope to make sure your "12 volt source" is a steady DC power supply, not a signal, before you hook arduino power to any other pin besides batt on the OBD port.
Step 3: Wiring OBD Port to CAN Board
Look on the pinout for your OBD port for CAN Low and CAN High. Connect those wires to the High and Low on your board.
Now use the ground from your OBD port as your ground for this project! Connect all the ground wires together, and make sure they are grounded to this OBD port.
We will focus on the rest of the CAN board's SPI interface in a few steps.
Step 4: Fuse Tap and DC to DC Converter
Don't skip the DC step-down converter! I accidentally destroyed this project once already because I decided would run the Arduino off of 12 volts from the fuse box. I think there was a voltage spike from an inductor somewhere (Arduino was hooked to the same fuse as the windshield wiper motor), and it fried my Nano.
Check out the photos! I had my first version all soldered together. It was nice and clean! But missing the DC step down... I had to unsolder everything and re-create the device with a new Arduino. Don't cut corners like me!
Connect the Vin- of your buck converter to your OBD ground. Connect the Vin+ of your buck converter to your 12 volt source [fuse tap]. Make sure your fuse tap is the right kind. Your car may have ATO, ATC, ATC-lp, or Micro2 size fuses. You need to buy the right size. Check before you buy.
Now you need to adjust your output voltage. You must connect some kind of load accross the output of the converter. Try a lightbulb, resistor, or your Arduino Vin (if you're careful!). You must adjust this voltage to somewhere well within the operating range of your components. Check your display and CAN bus data sheets to see if they need 5 volts or 3.3 volts. Again, make sure your load is attached when adjusting the voltage.
I spliced a single cable into two to supply the Arduino and the CAN board (y-shape). I did the same for Vcc and ground.
Step 5: Arduino
Time to connect it all together. Your configuration will be different from mine. Since I am using the Teensy 4.0 board, my pins are different for each interface. Simply consult a pinout chart for your device to figure out which pins you need to connect to. You need to find the following pins on your microcontroller:
CAN Board SPI: connect directly -
- MOSI (slave in)
- MISO (slave out)
- SS (chip select/slave select)
- CLK (clock)
You MAY need a pullup resistor for your i2c interface. Do some research and figure out if it is needed with your configuration.
Display: connect directly (assuming you are using the same OLED that I am using) -
- SDA (serial data)
- SCL (serial clock)
Don't forget to connect Vcc and GND to your OLED. You will want to wire all four of those wires into the four-conductor wire that will go up to your dashboard. I recommend using a jumper wire with pins so that your screen is detachable. It will make your installation easier.
Step 6: Code
This is the tricky part! I spent a lot of time experimenting with the protocol. Coming up with the code was very hard. However, it is really quite simple. I have left you lots of comments! Go through the code and try to understand what is going on.
It is hosted on GitHub. I am currently writing a desktop utility (see photos) and working on other firmware improvements. Stay tuned! Get in touch with me if you are interested in the software development updates.
Step 7: Enclosure Design
Now it is time to design your screen mount and hardware enclosure. I am not going to include Fusion360 files because I printed about six different versions of my screen bezel trying to get a good fit. I changed my conductor wire, mount location, and bezel size. My dashboard will also be at a different angle as yours. My recommendation to you: design your own! If you REALLY want the CAD files, just reach out to me and I will post them on GitHub.
You must consider where you are mounting your screen, and you must also consider where you will put your Arduino. I found a little cavity right between the fuse box and parking brake, measured it, and designed a custom box that fit it perfectly. Your parts will be different size. You can adjust the size of the enclosure based on whether you soldered or just used jumper wires to connect the pins.
I encourage you to use the few photos I have attached as inspiration for your own custom design.
Step 8: Installation
Time to route your wires and install. If you are like me, you are going for permanent installation. I will be printing a cover for the OBD port to cover the exposed wires. Check out my final enclosure design, neatly fitting into the small space between the brake and the fuse box.
I routed the wires up through the back of the dash behind the steering wheel. I advise you to be careful! Don't do anything stupid. Be careful when running your wires. Lots of important stuff down there. Knee curtain airbags, parking brake, hood/gas filler door release cable, gas and brake pedal...don't run the wire in front of anything important.
Congratulations on your new scan gauge!
Participated in the