so that’s different
it seems people often approach this concept with an Arduino/NetDuino/PIC/etc, plus a shield or some custom circuitry, and a bit of custom code. depending on your end goal, a microcontroller could be the best approach. however, this article is about getting started quickly and cheaply by leveraging a standard ELM327-based OBD-II scan tool (~$25) and your laptop, tablet, phone, Raspberry Pi, etc.
note: we’re not talking about “pulling codes” or clearing the check engine light, that’s everyday stuff. we want to control and get info from accessories attached to the more interesting buses.
all aboard the short bus (background)
in 1996 a federal law took effect requiring most new consumer vehicles in the US to have standards-based On Board Diagnostics, called OBD-II. the OBD regulations were put in place by the EPA for monitoring emissions related components, but the systems have evolved to be much more capable.
the good thing about OBD-II was it defined a limited set of network types that a car maker could implement for the emissions related diagnostics. this meant that tools to interface with those networks could also become standardized and inexpensive. called scan-tools, they come in full-featured versions with built-in software/display/buttons, and dumb versions that must be connected to a PC/Mac/tablet/phone to be useful.
what follows is information on how to use one of these inexpensive scan-tools (the dumb USB, Bluetooth, or serial-port kind) to interface with a vehicle in ways it wasn’t exactly intended.
a couple ones that i’ve personally had success with:
- USB: ScanTool ElmScan 5 (from Amazon…)
- Bluetooth: BAFX Products ELM 327 Bluetooth OBD2 scan tool (from Amazon…)
step by step
the challenge: OBD-II standards only apply to the emissions related portions of a vehicle bus. other systems often operate on an entirely different bus which may or may not use the same protocol as the OBD-II diagnostic bus. even worse, the non-emissions-related bus data is proprietary manufacturer info that can vary for each make/model/year.
the good news is that for simplicity and cost-savings, most manufactures only implement a single network type during certain year ranges. since they have to use one of the standard OBD-II protocols for the diagnostic bus, they might as well use the same protocol (or a slight variation) on the other buses. this is why we are sometimes able to use a scan-tool to interface with a non-OBD bus.
from a high level, we need to:
- determine what protocol(s) our car uses
- make the physical connection
- test the interface
- start hacking
now onto those details…
step 1: which protocol?
vehicles usually have at least 2 buses, the main diagnostic bus and an interior or comfort bus. the diagnostic bus often has access to all the drivetrain components as well as the OBD-II emissions stuff. the simplest vehicles to hack are the ones where all the buses use the exact same protocol and all relay messages to each other. some vehicles may have the secondary buses connected to the diagnostic bus through a gateway that may only relay information when queried with the correct command. other vehicles use the same overal protocol on all buses, but different speeds.
buy a Factory Service Manual for your vehicle if at all possible. it will almost always tell you what you need to know to at least get connected and is full of great info. you can get FSM’s used on eBay if your vehicle is a few years old or get the PDF version if you can find it. online tech libraries like AllDataDIY may have complete service manual info too. public libraries sometimes have subscriptions to those services. don’t forget to just Google for your make/model and “OBDII protocol”, “OBD bus”, etc.
we are ultimately looking for the exact protocol that our target bus uses and any information about the messages that components on that bus send/receive. if we don’t have this info, we can still try connecting to the diagnostic bus and hope it relays from our target bus.
the OBD-II spec allows for the following protocols: SAE J1850 PWM, SAE J1850 VPW, ISO 9141-2, ISO 14230-4 KWP, ISO 15765-4 CAN, SAE J1939 CAN. if our target bus uses one of those, or if the target bus relays to the diagnostic bus, then we can continue with our hack of using a scan tool to interface with it.
example: i was able to find online that my 2003 Jeep Grand Cherokee (WJ) actually supported 2 different protocols for the OBD-II system (due to a factory mistake). the FSM cleared up which one was the native protocol for the “Chrysler PCI Bus” (SAE J1850 VPW). it also confirmed that the radio and steering wheel mounted remote-control buttons communicated via that PCI Bus. using those buttons to control something else was my personal end-goal.
step 2: physical connection
the OBD-II spec requires a standard diagnostic port to be located within 3 feet of the driver and be accessible without tools. usually it’s under the dash, right above your feet, and looks like this:
this is often the simplest place to access a bus. these ports will have certain standard pins populated depending on which OBD-II protocol the vehicle uses. there are also pins left undefined by the spec. car makers often bring out access to other buses on these optional pins so that their own proprietary scan tools can interface with the entire vehicle. consult that Factory Service manual you bought for your connector pinout or wiring diagram. here’s the standard vehicle-agnostic pinout info:
important note: at this point you should move on to step 3 and try the main diagnostic bus first. if that doesn’t get you the info you want, then come back here for how to tap into the correct bus directly.
if your vehicle’s diagnostic port does have pins with access to the target bus, then you can take apart your scan tool and swap wires from the standard pins to the target bus pins. otherwise you may need to actually splice into a wire harness somewhere in the vehicle. you can get an OBD-II extension cable from Amazon/eBay for cheap and hack off the vehicle end to give you raw wires to play with. tip: the radio wiring harness is often a great place to get at the interior/comfort bus.
example: my FSM told me that pin 3 of the diagnostic port went to the radio-related bus. since my Grand Cherokee uses the single wire J1850-VPW protocol, i only had to swap one wire inside my scan tool from pin 2 to pin 3 to get a direct connection to the bus i was interested in. i later found out that all the buses in my particular vehicle relay between each other and so i didn’t really even need to do that.
step 3: basic first tests
if you’re still reading then you’ve probably had all the background info you can stand and are dying to get to some actual hacking. bear with me as there’s one more bundle of knowledge required – how to actually use an ELM327-based scan-tool to read and write bus data.
these scan tools use the ELM327 IC from Elm Electronics (or more likely a clone). we can interact with the IC using AT commands similar to modems from back-in-the-day.
to get started exploring, you need a serial port terminal application (even for USB and Bluetooth devices, they create virtual serial ports). HyperTerminal for the PC has a free trial, goSerial for the Mac is free, and there’s Slick USB 2 Serial Terminal for Android 3.1+ in free and paid versions.
connect your scan tool to your vehicle and computer or Android device (iOS devices might work also, i haven’t had a chance to check into it). turn your vehicle on (the key in “run”, no need to actually start it). pull up your serial terminal program and connect to the scan-tool. check the manual for connection settings. nearly every one that i tested used the following:
- Speed/Baud: 115200
- Data Bits: 8
- Parity: none
- Stop Bits: 1
- Hardware Flow Control Input: none
- Hardware Flow Control Output: none
once connected, type the command
ATI and press enter. you should get back
ELM327 v1.4b (the version might be different). if nothing comes back, try
ATZ instead and wait a couple seconds for the device to reset. if you don’t get anything back or you get random looking characters, you probably have the baud rate set wrong in your serial software. i did try one odd scan tool that used a rate of 9600 when not connected to the vehicle and 38400 when connected.
once you have verified that your connection to the scan tool is working, then we want to verify the scan tool’s connection to the vehicle is working. issue the command
ATSP0 to tell the tool to use automatic protocol selection (you should get back
OK). then issue
ATMA and you’ll get back a stream of data (sets of hex numbers to be exact). just press enter again to stop the stream. if you don’t get any data back, then double check the scan-tool’s connection to the vehicle and that the vehicle is on.
if you know for sure which protocol your vehicle is using, you can try setting the tool for that instead of automatic. issue
ATSP# but replace the “#” with one of the following designators:
- 0 – Automatic
- 1 – SAE J1850 PWM (41.6 kbaud)
- 2 – SAE J1850 VPW (10.4 kbaud)
- 3 – ISO 9141-2 (5 baud init, 10.4 kbaud)
- 4 – ISO 14230-4 KWP (5 baud init, 10.4 kbaud)
- 5 – ISO 14230-4 KWP (fast init, 10.4 kbaud)
- 6 – ISO 15765-4 CAN (11 bit ID, 500 kbaud)
- 7 – ISO 15765-4 CAN (29 bit ID, 500 kbaud)
- 8 – ISO 15765-4 CAN (11 bit ID, 250 kbaud)
- 9 – ISO 15765-4 CAN (29 bit ID, 250 kbaud)
- A – SAE J1939 CAN (29 bit ID, 250 kbaud)
i always issue the following commands to get the scan tool into a baseline state (enter them one at a time, you should get back
OK for each one):
ATAL. that will ensure that you see human readable data, which will enable us to analyze what’s going on. most scan tools will remember these settings between uses.
for more information on interacting with the ELM327 IC (and to lookup what those commands did):
step 4: start hacking
that last datasheet, combined with the info in this post, should be all you need to start hacking!
my next post (part 2) will give more detail about how to get what you want out-of or in-to the bus. i’ll be covering:
- the bus message structure
- a real-world example of how to find what messages you care about
- how to send msgs into the bus to control components