OBD Reader

From OpenMBD
Jump to: navigation, search


General description

OBD stands for On Board Diagnostics, since the introduction of the second version of OBD, simply named OBD2, there is a standardized list of Diagnostic Trouble Codes. Similarly there are standard Parameter ID's to get information like the throttle position and RPM from the car. OBD2 supports several communication protocols but cars from 2008 must have a CAN implementation. So it is possible to read out the OBD2 information when you can send and receive CAN messages. This section shows how you can do this with the E407 and HANcoder.

Hardware

SN65HVD230.JPG

To connect the E407 to the car some hardware is needed. The E407 doesn't have a CAN transceiver so this has to be mounted externally. For this example we will use the SN65HVD230 but you can use another transceiver if you desire. Now we still need a cable between the car and the SN65HVD230. For this OBD2 cables are available on the internet, just search for OBD2 connector or J1962 connector.

OBD-2-OBD2-OBDII-EOBD-JOBD-ODB-ODB2-ODBII-EOBD2-OBD11-ODB11-font-b-J1962-b.jpg

Connection diagram

ConnectionDiagram


Simulink Model

A simple simulink model has been made to illustrate how to get the information from the car. To understand this section some knowledge about the OBD2 protocol is required. It should also be understood that there is a limit to the amount of messages that the car can send, thus the rate of information depends on the amount of different PID's that are requested. This is not a limit of the CAN bus bandwidth but of the implementation of the protocol in the car.

Download the model (VehicleLogger) of which the OBD2 reader is part.

Initialisation

The OBD2 information will be read over CAN so the CANbus should be initialized. In this example CAN channel 1 is used for the OBD2 communication. According to the standard the baudrate can either be 250kb/s or 500kb/s and the identifiers can be normal (11-bit) or extended (29-bit). Check the baudrate and identifier type of your car and use these in the CAN initialization block. In this demo we will be using a Volkswagen Up and it has a 500kb/s CAN bus and it uses the standard identifiers. A CAN config block must be included in the model to activate the CAN bus.
OBD2 CANsettings.png

In the picture above of the CAN config block parameters it can be seen that the baudrate is set to 500kbit/s and the reception filter Mode is set to 'Receive both 11- and 29-bit identifiers'. The settings on the generic tab are left at the default settings.

Sending the PID requests

The OBDII protocol works with a request-answer sequence. To get data from the car, a request message is sent. This message consist of the number of bytes of the message, Current data (1) or freeze frames (2), PID1 request, PID2 request and at last four zero’s (The four 0’s are not used but each OBD2 message must have 8 databytes).
OBD2 CANsendRequest.png
The OBDII ID of the CAN message is a standardized hexadecimal value: 0x7DF. The ID is the Constant value in a constant block. The Number of bytes, PID1 request and PID2 request are controlled by the Counter Limited. The counter needs to be adjusted depending on how much PID’s you want to receive.

e.g. The desired information is available in 8 different PID’s. The Counter Limited has to count till 8. For each input port there is a 1-D Lookup placed. With each count of the counter the 1-D lookup gives the right Parameter ID for the input port of the CAN send HANcoder block.

If two PID's can be requested at once the 'Number of Bytes' in the CAN message should also change, this is also done with a lookup table. The three lookup tables must match. In our example we use 1 lookup table for the 'number of bytes', 1 for the first PID and 1 for the seconde PID. Below the settings of the three tables is shown.
OBD2 lookupNrOfBytes.png
OBD2 lookupFirstPID.pngOBD2 lookupSecondPID.png

When the counter is equal to 0 the program will send a request with 3 data bytes, requesting PID 4 (calculated engine load) and PID 70 (Ambient air temperature). When the counter is 2 the program will send a request with 2 data bytes, requesting PID 12 (Engine RPM)

Receiving the data

The car will respond by sending a message with identifier 0x7E8. The first byte will indicate the number of bytes in the message, the second byte indicated the service ID. Then, byte 3 indicates the PID of the data that is being send, byte 4 (A) is the first byte of the data. If two PID's were requested both only consisting of 1 data byte the next byte will hold the PID of the second request. If only 1 PID was requested, as is the case with the Engine RPM, byte 4 (A) and 5 (B) are both holding the data. The engine rpm is stored in a uint16 and thus requires two bytes.
OBD2 receiveSection.png
When a message is received the number of bytes and the (first) PID are checked in a subsystem. A lookup table holds the number of bytes per PID, if the message contains more bytes than if should have when only sending the data of the 1 PID it is an indication that 2 PID's are send in 1 message. If you change this model to see other PID's do not forget to also adapt this last lookup table.
OBD2 receiveMessageTypeDetection.png

When this is the case a special subsystem:'Combined messages data routing' is enabled. In this subsystem the data is only let through from 'CAN Receive' block to 'Combined Message Processing' when the subsystem is enabled.

Processing the data

If the message is a combined message the 'Combined Message Processing' subsystem checks which PID's are in the message and process the data according to the specification. Often this consists out of a simple offset and/or gain. An example can be seen below where the value received is multiplied by 100 and then divided by 255 to give a calculated engine load between 0 and 100%.
OBD2 receiveDataProcessing.png

There is a 'Time Out Check' subsystem to check how long ago the PID has been last received, when this exceeds a user specifiable timeout time the output of this subsystem will become high. When the timeout has occurred the switch will switch from the data processing subsystem to a user specifiable error value.

In the 'single messages processing' the same process happens with the exception that here 2 data bytes are processed instead of one. Again the error value can be given when a PID hasn't been received for the timeout time. The error values are used in the last subsystem: 'Signal selection'. A switch checks if the first value is larger then the error value, if it is the first input is passed through, else the second input is passed though. This means the error value must be lower than any expected value of the OBD2 PID data. In our example -3000 is used as error value.
OBD2 receiveSwitch.png

That concludes the data processing of the received PID data.

General remarks

  • If a PID isn't available in the car, the car will simply not respond to the request.
  • The CAN identifier for sending a request is 0x7DF for standard (11-bit) message and 0x18DB33F1 for extended messages. Note however that you will need to set the first bit of the extended identifier to let the HANcoder blocks know it is an extended identifier. So 0x18DB33F1 becomes 0x98DB33F1.
  • The CAN identifier for receiving a data message is 0x7E8 for standard (11-bit) message and 0x18DAF110 for extended messages. Note however that you will need to set the first bit of the extended identifier to let the HANcoder blocks know it is an extended identifier. So 0x18DAF110 becomes 0x98DAF110.
  • If you send data to the car but the vehicle is not turned on yet, the CAN bus will not get an acknowledge and the CAN buffer will overflow. So start the OBD2 reading after starting up the car's CAN bus.
  • A list of PID's can be found on Wikipedia OBD-II PID's

Vehicle Logger

This is part of the Vehicle Logger example, the next step for this example is building the GPS block the previous step was the MPU6500 6DoF sensor.

See Also

CAN Send |CAN Receive |CAN config