CAN-BUS based OBD reader

DISCLAIMER: -

Please note that automotive is very risky environment due to the high temperature involved and due to all the flammable plastics covering the inside of a car. Hence, you should be fully aware of whatever hack you do on your car and understand the risk involved in the process.

I have spoken on my video to use the board on my car, but that will not be until I do more refinement to the design (and hence not anytime in near future, due to my time scarcity). Certain parts in the hardware such as the 3.3V LDO gets significantly hot when connected to the 13.5V of car (that’s usual for all linear regulators) and that might be a potential cause of fire!!

Information provided on this website is meant to be a proof of concept only and certainly not the final design.

OBD II port and CAN BUS: -

OBD = On board diagnostic is a port (connector) available on all latest models car which can be used to know the working of the vehicle using various protocols such as: -

1. CAN bus

2. Variable PWM

3. K/ L line

Detailed information about these protocols can be found in the Wikipedia link: -

http://en.wikipedia.org/wiki/On-board_diagnostics

I did some tests on my car (Hyundai - i10) and confirmed that it uses CAN-BUS as communication protocol and runs on the following setting: -

1. 500kbps speed

2. 11-bit standard ID CAN-BUS.

More information about CAN-BUS can be found from the Wikipedia link: -

http://en.wikipedia.org/wiki/CAN_bus

Hardware description: -

The hardware consist of the 2 main ICs (integrated chips) – dsPIC33FJ128MC802 (3.3V) and MCP2551. You can use any Microchip’s device for CAN communication which has CAN/ ECAN peripheral module. Alternative device could be PIC18F4585 (5V) or dsPIC30F4011 (5V) etc.

MCP2551 is a CAN transreceiver that converts the CAN_TX and CAN_RX signal from the controller to differential signal that is needed for CAN bus. For more information, you can refer to the data sheet of MCP2551. Also, note that CAN bus needs a termination resistor of 120ohms across the CAN signal wires.

The controller that I choose (dsPIC33FJ128MC802) is a 3.3V device while the other interfacing devices viz. MCP2551, LCD are 5V and hence we need suitable voltage level converters. The reason for me to choose the 3.3V dsPIC is because, I would like to interface a SD card in future and for that 3.3V controller is simpler. Also, Microchip has provided file system stack for SD card which can be used straight on dsPIC.

3.3V to 5V level translator for MCP2551: -

Refering to the hardware schematic, I have used 2 NPN transistors to convert the 3.3V pulses from dsPIC to 5V pulses. I did not use any PNP transistors as they have limited speed; keeping in mind that our CAN will run at 500kpbps. The first transistor converts the 3.3V to 5V inverted logic and second transistor invert the logic again (no voltage level translation). Since dsPIC can supply 4mA max from each pin, a 650ohms resistor is used to drive the first transistor.

3.3V to 5V level translator for LCD: -

No voltage level translator used for LCD as the dsPIC has some pins which are 5V tolerant. I specifically used those 7 pins for interfacing the LCD and hence no level translator used. LCD uses standard software in 4-bit interfacing mode.

Voltage regulators: -

The OBD connector provides the battery supply thro one of its pin. I used LM7805 to convert the 13.5V battery voltage to 5V to power MCP2551 and LCD. I also used LM1117 to convert 3.3V to power dsPIC and SD-card (in future). Decoupling capacitors are used wherever necessary.

This schematic is also available as PDF copy at the bottom of this web page.

Both the pictures are of the same board with different lighting.

Since, I could not get a DIP version of MCP2551, I had to manage with SOIC MCP2551 and a small board to convert from SOIC to DIP.

Software description: -

The software is a modified version of Microchip application note AN1249. The modifications made are: -

1. Baud rate changed to 500kbps

2. Code for extended ID (29-bit ID) commented out for ease of my understanding.

3. Code modified to send the ID for ECU and PID for specific measurements.

4. Code for LCD added.

The communication for OBD using CAN is pretty straight forward. The request to ECU is sent from the OBD reader using the ID à 0x7DF and ECU replies back with the ID 0x7E8. This is very much a standard for most car with 1 ECU (like my car), for more complex car (like Hybrid cars), the protocol might be different. Since my dsPIC (OBD reader) should always receive CAN messages with ID 0x7E8, the same is used as a CAN message receiver filter.

Using the ID, the request can be sent to ECU to read a number of parameters like engine RPM, coolant temperature, engine load etc. Such request are sent by byte-2 of CAN message and the specific request numbers are called PID. A detailed list of PID is available on Wikipedia: -

http://en.wikipedia.org/wiki/OBD-II_PIDs

Steps for OBD reader software: -

1. Initialize CAN module for 500kbps.

2. Use standard (11-bit) ID settings. No need of extended (29-bit) ID.

3. Set receiver filter to 0x7E8.

4. Enable receive interrupt.

5. Initialize LCD module.

6. Set the transmit CAN message packet as below: -

a. canTxMessage.id=0x7DF;

b. canTxMessage.data[0]=0x02;

c. canTxMessage.data[1]=0x01;

d. canTxMessage.data[2]=ENGINE_SPEED_PID;

e. canTxMessage.data[3]=0x00;

f. canTxMessage.data[4]=0x00;

g. canTxMessage.data[5]=0x00;

h. canTxMessage.data[6]=0x00;

i. canTxMessage.data[7]=0x00;

j. canTxMessage.data_length=8;

7. Transmit the CAN packet.

8. Inside “while” loop, wait for CAN message to be received.

9. If the CAN message is received, it will be for sure from the ECU (because, we set the filter accordingly), check the message byte – 2. Accordingly, convert the byte -3 and 4 into human readable message format and display over LCD.

The software code is available at the bottom of the web page.

DEMO OF MY CAN BUS OBD READER (on Hyundai i10): -

DEMO OF SCANGAUGE ON: -