About the Project
The last years I have been working on this project at university and want to share at least some basics. The whole project is really complex involving a datalogger management platform, wifi server upload and automatic database import, software version managment, data processing with online viewer and so on...
If you are interested in more scientific projects of my former research group, check out their links page:https://www.linkedin.com/company/tum-smart-mobility/
Vehicle Diagnostic Protocols
Vehicle manufacturers are engaged by law to provide an OBD-II socket in every car. This is intended for emission control and workshop diagnostics in case of malfunction, all covered by the OBD-II protocol. But manufacturers also use it for their extended diagnostics of subsystems. This needs some further knowledge on vehicle diagnostic protocols. Different manufacturers, models series and production year use different protocols. This article shows some insights into these different protocols and how to handle them.
Diagnostic Protocols used in an automotive environment are in general request-based and can be divided in transport protocols (ISO-TP, TP2.0) and application protocols (UDS). Most modern vehicles use ISO-TP and support UDS functions to read data from storage registers, like service Read Data by Identifier (0x22). The description of the data stored in these registers is defined by ODX and may vary for each ECU and vehicle model. ODX definitions are normally not publicly available, but can either be implicitly extracted from workshop test equipment by matching the CAN Bus traffic with the requests and actual data displayed as reference or just by reverse engineering without reference values by triggering states and events on the vehicle leading to known signal paths.
Most diagnostic protocols use CAN bus as a physical transport layer. But you need to differentiate to CAN messages used in normal automotive applications, where there is amassage with a fixed ID containing some data. In diagnostic protocols, there are sessions, multi-part messages, and functional addressing. Without a request triggering an ECU to reply, there is no information at all. This implies to handle with timeouts, negative responses and timing requirements according to request scheduling.
This illustration gives an overview of the diagnostic and transport protocols used inmodern vehicles. The old KWP2000 protocol also is partially included in the UDS specification.
You see, all current diagnostic protocols are included in UDS, and transported over ISO-TP (some older VW use TP2).
The UDS specification includes a wide range of functions, most applications get alongwith a fraction of it. And that’s how it’s handled: A application normally only supports thepart of UDS ist uses, do not expect more than that.
There is a nice overview of the TP2 protocol on http://jazdw.net/tp20
And also for ISO-TP, there is much information available, already. And it’s not that complicated. So I’ll focus on diagnostic protocols instead.
UDS is the new standard used by almost every manufacturer. It provides different services from a simple E-OBD request up to authentification and ECU firmware flashing. Most of the functions are not relevant for normal users, because the specification only defines the way of access and transport structures but no specific data, memory addresses and credentials you need to access these functions.
For just reading values, you only need two commands:
- 0x10 Diagnostic Session Control
- 0x22 Read Data By Identifier
The first one 0x10 tells the ECU to switch to another diagnostic mode, in our case we need “Extended Diagnostic Session” (0x03)
After a positive response of the ECU, we can read registers with “Read Data By Identifier”(0x22).
Now we know how to read values, but not from where and which ECU. Here the difficulty begins. You can try to find some values on the internet, often called “custom pids” or “extended pids”. Another solution is to get a workshop tester that can perform this request and sniff them. This provides the functional address of the ECU you want to talk to and the registers the data is stored in. If you get the actual readings of the values you request, it is easier to get the conversion formula as well.
For VAG vehicles (VW, Audi, Skoda, Seat, Porsche) there is the VCDS tool and with the help of my decoder (https://github.com/TUMFTM/uds-decoder) it is pretty easy to find data registers and conversion formula.
Here is an example on a multi request with different ECUs and OBD and UDS read data combined:
7DF 02 01 00 00 00 00 00 00 <= Request supported OBD PIDs 7E8 06 41 00 98 18 00 11 00 => Response OBD PIDs ECU1 7EE 06 41 00 98 18 80 01 00 => Response OBD PIDs ECU2 710 02 10 03 00 00 00 00 00 <= Request Extended Diagnostic Session on ECU id 0x710 7E0 30 00 05 00 00 00 00 00 <= Control Frame for VIN Request 77A 06 50 03 00 32 01 f4 aa => positive response Extended Diagnostic Session7E0 02 10 03 00 00 00 00 00 <= Request Extended Diagnostic Session on ECU id 0x7E0 7E8 06 50 03 00 32 01 f4 55 => positive response Extended Diagnostic Session7E0 03 22 14 73 00 00 00 00 => UDS Read Data at 14 73 7DF 02 09 02 00 00 00 00 00 <= Request VIN 7E0 03 22 16 18 00 00 00 00 <= Control Frame for VIN Request 7E8 10 14 49 02 01 57 56 57 => Response VIN Block 1 (replaced actual VIN) 7E0 03 22 f4 0d 00 00 00 00 <= UDS Read Data at f4 0d 7E0 30 00 05 00 00 00 00 00 <= Control Frame for VIN Request 7DF 02 01 04 00 00 00 00 00 <= Request OBD Read PID 04 7E8 21 AA AA AA AA AA AA AA => Response VIN Block 2 7E8 22 AA AA AA AA AA AA AA => Response VIN Block 3 7E8 04 62 f4 0d 00 55 55 55 => UDS Response Read Data at f4 0d = 00 7EE 03 41 04 ff 00 00 00 00 => Response OBD Read PID 04 = FF 7DF 02 01 05 00 00 00 00 00 <= Request OBD Read PID 05 7DF 02 01 0c 00 00 00 00 00 <= Request OBD Read PID 0C 7E8 03 41 05 ff 00 00 00 00 => Response OBD Read PID 05 = FF 7EE 03 41 05 ff 00 00 00 00 => Response OBD Read PID 05 = FF 7DF 02 01 0d 00 00 00 00 00 <= Request OBD Read PID 0D 7EE 03 41 0d 00 00 00 00 00 => Response OBD Read PID 0D = 00 7DF 02 01 04 00 00 00 00 00 <= Request OBD Read PID 04 7E8 03 41 0d 00 00 00 00 00 => Response OBD Read PID 0D = 00 7EE 03 41 04 ff 00 00 00 00 => Response OBD Read PID 04 = FF 7DF 02 01 0c 00 00 00 00 00 <= Request OBD Read PID 0C 7E8 04 41 0c ff fe 00 00 00 => Response OBD Read PID 0C = FF FE 7EE 04 41 0c 00 00 00 00 00 => Response OBD Read PID 0C = 00 00 7E0 03 22 f4 42 00 00 00 00 <= UDS Read Data at f4 42 7E0 03 22 10 26 00 00 00 00 <= UDS Read Data at 10 26 7E8 05 62 f4 42 33 5a 55 55 => UDS Response Read Data at f4 42 = 33 5A 7E0 03 22 11 6b 00 00 00 00 <= UDS Read Data at 11 6B 7E0 03 22 11 6a 00 00 00 00 <= UDS Read Data at 11 6A 7E8 05 62 11 6b 2c 40 55 55 => UDS Response Read Data at 11 6B = 2C 40
Softing provides a cheat sheet for UDS with some information and examples:
The Data Logger
The hardware consists of:
- ESP32 WROVER B (16MB Flash + 4 MB SPI RAM)
- ublox MAX M8W GNSS
- BMP280 pressure sensor
- LSM6DSM 6-axis IMU
- MCP2517FD CAN controller and TCAN 334G transceiver
- microSD socket
- LT8609 low Iq DCDC
- LED and programming/extention socket
The device is designed to be running 24/7 on a cars 12V battery. Therefore a low standby current is needed, wich is archived by low power deepsleep of the ESP32 and a loadswitch physically switching off all unneeded components like SD card and GPS (V_backup keeps RTC running) resulting to ~1mA@12V. Wakeup can be triggered by CAN communication, IMU movenemt or periodically wakeup with input/battery voltage checking.
For low power voltage measurement the voltage devider is switched on by a P-MOSFET triggered by a capacitor. The MOSFET opens for a short time until the gate voltage is pulled up again by the resistor. The voltage sensing takes place in this small time window. The timespan depends on the input voltage, as seen in the picture below.
The ADC of the ESP32 is so bad, a individual (per device) calibration is needed to get at least 0.2V accuracy within the 10-26V supply range. A single point calibration at 19V was sufficient in my case.
More to come...