Since 90s and 2000s cars sold in EU, US, Australia, and certain countries in Asia must implement OBD2 standard for car self-diagnostics and reporting purposes.
The OBD2 standard provides a port for accessing the car's controller area network (CAN) bus through which you can communicate with the car's electronic control units (ECUs). The standard mandates that port must be placed at least 50 cm from the steering wheel.
One of the straightforward ways to connect your Linux computer to your car is through a simple OBD2 to USB adapter. You can find these adapters, based on the ELM 327 chip (or its clones) on eBay or AliExpress for a few bugs.
For communication on the CAN bus, the car may use one or several protocols. This depends on the car's model. The ELM 327 provides translation between serial interface and most known protocols.
If your car does not support some car-specific protocols, you may not be able to access all car's features without purchasing specialized (usually more expensive) adapter or do some extra hacking.
For example Mazda3 BM, BN supports three protocols. ISO-15765-4, HS CAN ISO-11898, MS CAN ISO-11898 of which only the first protocol is supported by the ELM 327.
For communication you use two sets of commands.
- AT commands communicating with the ELM 327 chip, for setting up the connection to the car.
- CAN protocol commands. Depends on the protocol selected when connecting to the car.
Communicating with the adapter using screen
After plugging the adapter into your computer, the adapter gets powered through USB cable and you can communicate with it even without connecting it to the car.
If you purchased the Bluetooth or Wi-Fi adapter, these are powered from car's battery and will not work without plugging the adapter into the OBD2 port.
Connection to the adapter
-
Make sure you are a member of the
dialout
group to be able to access serial interfaces.If not execute
usermod -a -G dialout $USER
and re-login. -
List USB devices and pick the one that appeared after connecting the adapter.
E.g.,
/dev/ttyUSB1
-
Connect to the device using the "screen" terminal.
screen /dev/ttyUSB1 38400
Transfer speed should be described in the documentation to the adapter. Usually, it is
38400
.If the screen command is not available on your computer, install it with
apt install screen
Setting up the connection with the adapter
To communicate with the adapter, you will use AT commands. Commands are case insensitive, and you may type them with or without spaces. So, ATZ
and at z
are equivalent.
The >
symbol is used to differentiate command from expected result. Every command must end with ENTER.
Please note that the screen is a terminal emulator. This means, every character you type is sent directly to the ELM 327 chip.
-
Reset the connection to the adapter.
>ATZ LM327 v1.5
-
Enable result newlines.
>ATL1 OK
To avoid printing results on the same line as commands, thus making results more readable.
-
Enable headers (optional).
>ATH1 OK
When sending a command on the CAN, multiple ECUs may answer. To differentiate between these ECUs you may enable headers, which adds ECU information in front of a result. I.e.:
>01 00 48 6B 10 41 00 BE 3E B8 11 FA 48 6B 18 41 00 80 10 80 00 C0
Where the
48 6B 10
is header for a first ECU and the48 6B 18
is header for a second ECU.The rest of the examples in this document will not have headers turned on, since these were tested on a car where only one ECU responds to a command.
-
Print ELM 327 chip version
>ATI ELM327 v1.5
Communicating with the car
Connecting to the car
-
Checking the car battery voltage.
>ATRV 12.2V
The car voltage check is a feature which is built into the ELM 327 chip itself. This value is not pulled through the CAN bus.
Returned value will tell you:
- The adapter is connected to the car. Otherwise, you will see a value close to 0.
- Fuse powering the OBD2 port is not blown.
- Approximate voltage of the battery. Please be aware that ELM 327 chip may need calibration to report correct value. For that check the chip's documentation.
-
Select the CAN protocol.
As mentioned before, the CAN bus may support different protocols. To select the correct one, you may a) let ELM 327 chip to find the protocol for you (may not work), or b) find the correct protocol in a documentation and select it manually, or c) deduct the protocol from pins on the OBD2 port, i.e., different protocols use different ports.
Protocols supported by the ELM 327 (HEX value):
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) <-- Mazda3 BM/BN, Citroen Berlingo 3rd gen 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) B - USER1 CAN (11* bit ID, 125* kbaud) C - USER2 CAN (11* bit ID, 50* kbaud)
Let the chip to select protocol for you, and then print protocol's name:
>ATSP0 OK >ATDP AUTO
Select the protocol manually. E.g., for Mazda3 it is
ISO-15765-4 11 bit, 500 kbaud
>ATSP6 OK >ATDP ISO 15765-4 (CAN 11/500)
-
Test CAN communication.
Send an arbitrary command to verify connection with the car. The command prints a list of supported commands.
>01 00 41 00 FE 3F A8 13
Based on the selected protocol, you may get one of the error messages like
BUS INIT: ERROR
, orCAN ERROR
, indicating:- The adapter is not connected to the car, or the port is broken.
- Selected protocol is not supported by the car. You may try to manually select different protocols.
Sending CAN commands
The ISO 15765-4 CAN commands start with a service code, followed by a parameter ID (PID). You can find all standardized PIDs on Wikipedia.
A few interesting services:
01 - current sensor data
03 - show diagnostic trouble codes
04 - clear error codes
06 - continuously and non-continuously monitored systems (current, min, max)
07 - show pending diagnostic trouble codes
09 - vehicle information
0A - permanent diagnostic trouble codes
-
Get supported PIDs for the sensor data service.
Not all PIDs are supported by the car. To figure out which are supported, you can send the following command.
>01 00 41 00 FE 3F A8 13
The first two bytes in the response (
41 00
) are the command itself with added40
to mark the response.Remaining values, when translated into binary indicate whether the following PIDs (from
01
to20
hex) are supported by the car.In the provided example the value translates into
11111110 00111111 10101000 00010011
where the third byte may be interpreted as:HEX A 8 BIN 1 0 1 0 1 0 0 0 Supported? Yes No Yes No Yes No No No PID 11 12 13 14 15 16 17 18 -
Get engine speed
>01 0C 41 0C 13 90
A = 13 hex = 19 dec B = 90 hex = 144 dec rpm = (256 * A + B) / 4 = (256 * 19 + 144) / 4 = 1252
-
Get coolant temperature
>01 05 41 05 36
A = 36 hex = 54 dec temp = A - 40 = 54 - 40 = 14 C (cold start in winter)
Additional resources
- YouTube series on accessing car via OBD2, including GUI apps and Python: https://www.youtube.com/watch?v=kkdRdKbMhPI&list=PL878ACC00CF9E0693
- List of standardised PIDs: https://en.wikipedia.org/wiki/OBD-II_PIDs
- ELM 327 documentation will give you more AT commands for configuring the chip: https://www.elmelectronics.com Note that ELM electronics never released chip version 1.5, these chips are clones. You may use the 1.4 version documentation instead.
- Solution for resistor issue with some adapters: https://www.multiecuscan.net/forum/viewtopic.php?f=5&t=1493