a complete guide to hacking your vehicle bus on the cheap & easy – part 1 (hardware interface)

haxored?

modern vehicles have internal networks that provide access to nearly every major component and accessory – everything from the transmission to the cd-changer.

why hack it? because you can! maybe you want to install your own car-puter that will replace the radio and climate controls. or maybe you’d like to make your key fob roll up windows or remote-start. i’m sure you can think of something.

 

so that’s different

net-ardu-micro-propeller-thingy

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.

don't be a tool

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:

 

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:

  1. determine what protocol(s) our car uses
  2. make the physical connection
  3. test the interface
  4. 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:

government mandated access port

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:

count the pins!

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” (without the quotes) 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): ATL1, ATH1, ATS1, 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.

super cereal

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

 

part 2 of this series: http://theksmith.com/technology/hack-vehicle-bus-cheap-easy-part-2/

say something about this post

  • (will not be published)

34 responses to “a complete guide to hacking your vehicle bus on the cheap & easy – part 1 (hardware interface)”

  1. piercedRichard Reply

    Great info. I’m working in my 2002 WJs PCI bus for, among other things, aux audio in and, if possible, radio info display for audio track data.

    • theksmith Reply

      nice! what are you planning to use for the final hardware – tablet/phone, pc, microcontroller? i know the radio does broadcast what “mode” it’s in and which track or radio-preset it’s on. no idea how the audio input for the cd-changer/sat-radio actually works.

      • piercedRichard Reply

        Right now I’m looking at interface options – I have a generic ELM327 (clone, v1.5), but something isn’t the same. When I was reading the bus from the stock ODBII port, I was able to get vehicle information, but I couldn’t find anything specific from the radio (although several codes were going by when the ignition was in ACC, with the radio either on or off). I tried taking a few ODBII codes from your codebase, but I couldn’t emulate the steering wheel buttons (or sniff them from the bus). I connected the CD changer PCI bus connection in place of the ODBII Pin2 connection, and got the same data, but couldn’t find anything specific. It could also be something wrong with my ELM327 clone, but Torque works fine on my Android devices.

        I think I’m going to try a logic sniffer to see if something is missing, or even put a tap between the radio and the BCM to see what data is flowing from what direction. From what I remember, the radio checks either on power on or periodically for a CD Changer (probably the same with the stock amp, which also has a PCI bus connection).

        When I am done, I think I’m going to use an Android device or a Raspberry Pi as the controller, or I can work with the FreeSOC(freesoc.net). I have an old Android phone that I use for media now, which would be nice to change tracks via the steering wheel buttons as well. There is a commercial product for 2005+ Chrysler radios that seems to work, using Bluetooth to connect an Android phone to the vehicle audio and steering wheel buttons. It lacks the track display, though.

        Seems like a lot of work for something so simple, but my real reason for looking at the bus is to interface with a custom lighting system (LED arrays replacing all external lights except headlights, multiple colors, customized patterns, visualizations if possible…). I think that you can read the signal information from the bus as well (mainly to communicate to the instrument panel), which could be used to get vehicle controls into a controller (Arduino or FreeSOC).

        I did find an interesting wiring diagram on wjjeeps.com for the ODBII port, explaining a few additional wires. It looks like the additional wires are an RS-232-esque port used with Chrysler’s scantool, and for programming the ECM/BCM. More might be available there.

        I’ll have to see if I can find information on what preset the radio is on. The only codes I saw were simple 2-3 byte status updates with the ignition on ACC. Maybe one of those was it, since it was happening around every other second.

        Is your web server pretty decent? I’d like to send this link to hackaday.com for their review. It could cause a traffic spike for several hours. They’ve had a few other articles about ODBII hacking and radio control before, too.

        • theksmith Reply

          my shared server is mediocre but i do have several caching strategies, so it might hold up – i welcome the submit.

          my FSM pinout of the WJ OBDII port does not match that one on wjjeeps.com – mine basically has that several pins offer direct connection to different busses/modules (TCM, Radio, etc). i originally hooked directly to the radio one, but found i didn’t need to later. i can do a screenshot of the pinout diagram if you need it. however…

          be sure you are setting your scan tool for J1850 VPW protocol. the WJ actually supports ISO9141 and J1850 for the diagnostic bus (a factory “mistake”), but i don’t think the ISO9141 relays all the other busses. all of my scan tools defaulted to the ISO9141 and so i had to issue the ATSP2 command.

          good luck!

      • piercedRichard Reply

        I’m thinking about either an Arduino, Raspberry Pi, or a FreeSoC. Changes are that I’ll use the Pi, as long as there’s a good working Android interface for it. I want to tie together a custom LED kit for all external lights (minus headlights), so I can have audio visualizations and custom light flash patterns. I’m still pretty early in that (coming up with the first parts order now).

        I would think that I can read the turn signals and other light statuses from the bus, but we’ll see. I was only able to see a few codes that repeated when the vehicle was in ACC, but didn’t think to change the preset or mode to see if it changes.

      • Bruce McKinley Reply

        I’m trying to design a product that can plug unto the OBD II port, I am wondering if anyone tell me if there is a Pin in the OBD II port that will tell me when the Ignition of the vehicle is ON.

  2. Nick Reply

    I am able to get data to a OBD II diagnostic program but upon typing ATMA into my terminal it says “Searching…” and brings up no data. Any ideas?

    • theksmith Reply

      do other commands work, like ATI or ATDP? did you set the protocol manually or is it on auto? might try AT MA (note the space)… or try an ATZ (reset) first…
      also which scantool? mac/pc/android? what app are you using for a serial terminal?

      • DMacAttack Reply

        I have the same issue.
        ELM v1.2a. PC, teraterm. 2005 Dodge Magnum
        I looked through the ELM Datasheet, and it says when you select ATSP0 it chooses the automatic protocol selection, but will search when you send the next command. In this case it was the ATMA command. So its searching for the correct protocol. I tried leaving mine for 30 mins like this and it still didn’t find the protocol :(

        On mine I can read ATDP (which just displays the protocol which is currently selected, not the one that works for your vehicle). I can also read Voltage, system temp, etc, but still can’t read the memory. Its really strange, because I can read trouble codes using a Engine Diagnostic software utility. :S Anyone know a software utility that has a console output/ AT command wrapper to do the heavy lifting ?

      • Jesse Reply

        I am having the same problem as Nick is. I am using Android App ELM327 Terminal. (https://play.google.com/store/apps/details?id=Scantech.Terminal&hl=en)
        I am able to input commands like ATI and get “ELM327 v1.5″ back. I also downloaded the ELM electronics guide (http://elmelectronics.com/DSheets/ELM327DS.pdf) and found commands to read voltage (AT RV) and coolant temp (01 05) and both of those produce accurate results, so clearly the device is communicating with the car and takes the commands I give, but when I input AT MA I cannot get a stream of data. After a few seconds it says timeout. I tried to set the protocol manually and went through all 10 protocols with no change in result. When I set the protocol to automatic, I get the same result as Nick above where it says search, but shows nothing. Any thoughts? Thanks!

        • theksmith Reply

          Nick and i emailed a bit and tried to find the problem but i don’t know if he ever got anywhere. my only two thoughts are:

          - maybe the current cloned chips aren’t supporting AT MA correctly? note that there is no “real” ELM327 v1.5 (there is a 1.4b and a new 2.0: http://elmelectronics.com/obdic.html#ELM327). however i also have a cloned version which does work for me. i emailed Elm Electronics to ask who i could buy an “authentic” scan tool from and they were no help citing customer privacy concerns.

          - if your vehicles are using a CAN-Bus protocol, then maybe AT MA doesn’t work with that? i know the elm datasheet lists some CAN specific commands – perhaps there is one that is similar to MA just for CAN traffic? i haven’t looked into that yet as i don’t have any CAN vehicles handy.

          if anyone solves the issue, please do post here as it seems to be happening a lot, thanks!

  3. WayneKellen Reply

    I also had the problem they were having on a 2012 Dodge Ram 1500 4wd. I got no activity at all at the OBD2 port. I did tie into the Canbus High and Canbus Low wires behind the ignition switch. There I got activity on 2 different protocols. There was a 500k 11bit signal and a 125k 11bit signal there. I found that with the key off, the 500k signal is dead. However, the 125k signal is alive with no activity. As soon as the lock button is pushed, I have trouble with a “buffer full” error. I get some info, but very little. I am trying to track down the door lock and unlock commands. Without knowing what to filter, I have to do a ATMA command and it bombs really fast. My USB ELM327 cable I got off of Amazon came set to 38400, but I changed it to 115200 along with the port on my computer to match. It still gives me buffer full almost immediately. I suspect if they connect to the bus at a different location than the diagnostic port, they will have activity.

    Great article by the way!

    • WayneKellen Reply

      Here is a quick shot of what I got from the 125k ATMA before it errored. All I did was hit the remote lock button 1 time after I issued the ATMA command.

      >ATL1
      OK

      >ATDP
      USER1 (CAN 11/125)

      >ATH1
      OK

      >ATS1
      OK

      >ATAL
      OK

      >ATMA
      0B 3C 00 00 RTR
      0B 3C 00 00 RTR
      0B 3C 00 00 RTR
      0B 3C 00 00 RTR
      0B 3C 00 00 RTR
      0B 3C 00 00 RTR
      CAN ERROR
      0B 3C 00 00 RTR
      0B 3C 00 00 RTR
      0B 3C 00 00 RTR
      00 3C 00 00 RTR
      292 00 00 00 00 00 00 00 00
      0B 3C 00 00 00 00 00 00 00 00 00 00
      0B 3C 00 00 00 00 00 00 00 00 00 00
      0B 3C 00 00 00 00 00 00 00 00 00 00
      03 3C 00 00 00 00 00 00 00 00 00 00
      77B RTR
      03B RTR
      03B RTR
      03B RTR
      03B RTR
      CAN ERROR
      03B RTR
      03B RTR
      03B RTR
      03B RTR
      03B RTR
      00 48 99 C0 00 00 00 00
      00 48 99 C0 00 00 00 00
      00 48 99 C0 00 00 00 00
      00 48 99 C0 00 00 00 0
      BUFFER FULL

      >

  4. David Reply

    I think I understand why people are getting the searching error. There are a few things you need to make sure.

    One thing I noticed is if I don’t send the command ATSP0 before starting a scan it never works. It’s included in the setup instructions but not listed in the actual tutorial in part 2.

    The 2nd thing I noticed.. I am using a bench setup with a CAN-BUS gateway and a few modules. If I plug into my OBD port and there is nothing else active on the Diagnostic port there is no data to capture. I think the diagnostic BUS only reports data if there is requests on that BUS. That may explain why a few people get results from other BUS’s but not the diagnostic. Since I have another cable and program running on the diagnostic bus I can capture data when that program is active. Of course I can only capture data related to that programs activity.

    This may be helpful to identify exact activities if your program can send and perform tests on certain systems. In my case it’s an Audi BUS system and I can send tests such try locks or windows so I can capture those exact items off of the BUS without to much other traffic. My bench isn’t set up for that yet but it’s an example.

    Hope the insight helps some others having issues hacking their BUS. For clarification I am scanning CAN only and have no K-Line or Lin-BUS hooked up on my bench so I can confirm that an ELM clone version 1.5 (non Bluetooth) will work properly on a CAN network using the exact commands found in this tutorial. I seem to end every line in an error but I think it just may be a setup thing or the terminal software. It’s still not effecting the data capture I don’t think.

    Great work and thanks for time you put into making this information available.

    • David Reply

      Also I noticed I get a buffer full error if there is more than a few seconds of no activity on the bus so this may be what others are seeing as well.

      • theksmith Reply

        thanks for posting your experience and confirming that the basic commands do work on a CAN-BUS system as well!

        i think you are correct that many people are only connecting to the diagnostic bus, and therefore never seeing any idle traffic. on most newer vehicles the buses are not interconnected like my older Grand Cherokee – or at least they don’t forward traffic between each other unless you issue a specific command asking a gateway to do so. if someone is on a newer car and just connecting directly to the OBDII port, then this would be the scenario.

        i have a friend about to try some of this on a newer Jeep with CAN-BUS and we can’t find how to talk between buses, so the simplest way to work with the comfort bus looks like it will be to pull the radio and tap into its harness…

  5. Mariano Reply

    Thanks for the help. I don’t have much EE background so this is helpful. I am trying to replicate your example with this cable http://www.youtube.com/watch?v=0E7tBXDkexY but no luck so far. The Toyota diagnostic software works though with the same cable. Seems like it ought to work, but do I need a different piece of hardware? Thanks for any hints.

    • theksmith Reply

      what year/model is your yota? do you know which OBD protocol it’s using? also what’s your goal, do you want to interact with a certain accessory?

  6. J├╝rgen Reply

    I have started my own project after having troubles working with windows obd software and also with pyobd.
    The program has barely reached Version 0.0000001 but is able to get standard OBD Information.

    I have never got to read manufacture specific codes though.

    My goal would be hooking up an android tablet and control the music with my steering wheel and the music title showing up in the dash-display.

    The information on your page got me some steps further

    Thanks

  7. Fishy Reply

    A great guide, thank you! I am able to communicate with AT commands with my elm mini, but I cant get ATMA to work. Nothing is coming back? Every other command seems to work such as ATI and so on. OK i printed for every AT command I send. What am I doing wrong?!? Please give me some clues :-)

    • theksmith Reply

      thanks! what vehicle are you trying to work with? if it’s a CAN-BUS vehicle, then see the comments started above from David on September 10th, 2013 and my reply… (could be you need to tap into a different physical location or use the CAN specific commands)

  8. Jason Anderson Reply

    I have a 2005 Cobalt. I’m curious if anyone has enabled remote start or remote windows down using these guides?