In this blog I would like to discuss the firmware aspects of industry standard multi-protocol chip ELM327 or a compatible IC (like STN1110) for implementing an OBD scanner. First the article briefly discusses about the OBD as such and then dives deep into the implementation of firmware using ELM327 IC. As you can see ELM327 makes OBD related development a breeze ! It assumes that the reader has some familiarity with automotive protocols and the best and most authentic source is the relevant SAE standards.

So first we should understand what is OBD and OBD Scanner ?

OBD is an automotive term which stands for “On-board diagnostics”. OBD system consists of one or more Engine Control Units (ECUs) which can access all the sensors and actuators in the vehicle. So ECU can read all the sensor values( eg: MAF sensor, engine temperature sensor, oxygen sensor) and can control actuators ( eg: fuel injector, ignition coils, cooling fan) according to the sensor values. If any sensor or actuator is not working properly ECU can easily detect it and generate a diagnostic code which can be accessed through a vehicle port situated near the dashboard named OBD port. By reading this diagnostic code, a mechanic can easily trouble shoot it. OBD – 2 is the second generation obd system which describes a set of standards for interchanging of digital information of ECUs with outside world. Now a days hundreds of sensors and actuators are associated with each vehicle. OBD scanner is a device which can read real time values of all sensors and diagnostic code through OBD – 2 port.

OBD – 2 Protocols

OBD standard specifies different protocols. They are given below.

1. SAE J1850 PWM
2. SAE J1850 VPW
3. ISO 9141 – 2
4. ISO 14230 – 4 KWP ( 5 BAUD INIT )
5. ISO 14230 – 4 KWP ( FAST INIT )
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 )
10. SAE J1939 CAN ( 29 BIT ID, 250 KBAUD

Vehicle manufacturers can choose the protocol they want to use. However, in US all vehicles produced from 2008 are mandated to use OBD on CAN. So in modern vehicles we can expect CAN as OBD protocol.

Please see our earlier blog “OBD Faq” for more general information on OBD. You can find it here in our earlier blog post.

Introduction to OBD – 2 application layer message format

Irrespective of the lower layer (CAN, J1850, etc.), there is a standard format for obd -2 application layer messages. This is defined in SAE standard J1979. For heavy vehicles equiped with J1939, one has to refer J1939-73 standard.

Request format

This is the format used by a OBD scanner while requesting data from ECU

Format used by OBD Scanner ELM327


some examples of mode given below

0x01 : show current data
0x02 : show freeze frame data
0x03 : show stored diagnostic trouble code.

For reading the real time sensor value, we need only mode 0x01. In 0x01 mode, we can get current data of each sensor(real time) by issuing the pid

pid (paramter ID)

Some commonly used pid’s are listed below

0x00 : pid’s supported. It is not neccessory to support all the pid’s in every vehicles. So it is good to check the list of supported pid’s in the vehicle before attempting to read the sensor values. By issuing this command ECU will reply with 4 bytes information.

Other commanly used PIDs are

0x04 : engine load
0x05 : engine coolant temparature
0x0C : engine rpm
0x0D : vehicle spped
0x10 : MAF air flow rate

Command reply format

OBD Command Reply Format

Command status

command status indicates whether a command is success or fail.
In obd -2 standard,
success code = 0x40 + mode
For a mode 0x01 command 0x41 is the success code.


Reply bytes contains the pid of reporting data.


This is the requested data for that pid. We should process the data to get actual values.
Data length is depends on pid.

Some examples for command and its reply

Note : all requests , replies and datas are in hex format.

1. pid’s support
mode = 01
pid for obd support = 00
data bytes return = 4
Note that 41 is the success code for mode 01

command : 01 00
reply : 41 00 BE 3E 2F 00

PID Support OBD 2

41 – indicates command is accepted.
00 – indicates following data is for the pid 00.
BE 3E 2F 00 – actual data byte.

We can check the data byte what it means.

data byte obd2

Binary value 1 indicates the corresponding pid is supporting and binary 0 indicates pid does not support.

From the above ,

supported pid’s are 01,03,04,05,06,07,0B,0C,0D,0E,0F,13,15,16,17,18

We can get replies only for these PIDs.

2. engine rpm

mode = 01
pid for engine rpm = 0C
data bytes return = 2

command : 01 0C
reply : 41 0C 54 1B

Reply bytes indicates command successed for pid 0C and rpm data is 54 1B. Now we should process the data to get actual value. The scaling to be used for each paramter is defined in the OBD standard.

A = 54(hex) = 84(dec)
B = 1B(hex) = 27(dec)

scaling formulae

This is the scaling formula for rpm

rpm = ( ( 84 * 256 ) + 27 ) / 4

rpm = 5382.75

3. vehicle speed

mode = 01
pid for vehicle speed = 0D
data bytes return = 1

command : 01 0D
reply : 41 0D 3F
Reply bytes indicates command successed for pid 0D and vehicle speed data is 3F.

A = 3F(hex) = 63(dec)

vehicle speed

This is the processing formula for vehicle speed

speed = 63 km/h

4. engine coolant temparature

mode = 01
pid for coolant temparature = 05
data bytes return = 1
command : 01 05
reply : 41 05 17
Reply bytes indicates command successed for pid 05 and engine coolant temparature data is 17

A = 17(hex) = 23(dec)

coolant temp

This is the processing formula for coolant temperature.

coolant temp = 23 – 40 = -17 degree celsius

For more pid and its processing method refer the SAE J1979 standard

Introduction to ELM327

Communicating to external world, ECU must use one of the OBD protocols ( eg: CAN, SAE J1850, ISO15765 – 4 ). A CAN obd scanner can be used only for CAN supported vehicles, SAE J1850 obd scanner only for SAE J1850 supported vehicles.
So for each protocol there should be an individual scanner. By the introduction of
ELM327 IC we can build a single scanner very easily for many protocols. ELM327 IC with associated circuitary converts uart ( rs 232 ) message to obd format and vice versa. So we can simply issue OBD application level requests in ascii format to the ELM327 via UART port. ELM327 will convert it to the corresponding OBD message format as per the physical protocol used. Similarly, OBD reply from the vehicles are processed and OBD application level replies are send back through the UART. Firmware developer need not be worried about header bytes, messages formats, etc for each and every physical protocol. This is taken care by the ELM327.

We can configure and change the settings of ELM327 through AT commands. There are general OBD related AT commands as well as protocol related AT commands. Other IC’s which are compatible with elm327 ( eg: stn1110 ) have some more additional commands and settings.

Elm327 supports the following protocols

1. SAE J1850 PWM
2. SAE J1850 VPW
3. ISO 9141 – 2
4. ISO 14230 – 4 KWP ( 5 BAUD INIT )
5. ISO 14230 – 4 KWP ( FAST INIT )
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 )
10. SAE J1939 CAN ( 29 BIT ID, 250 KBAUD

Note that the protocol number assigned is also in this order.

Applying obd commands using ELM327

ELM327 has an UART interface on one end and OBD interface on other end. ELM 327 should have some additional circuitary for converting obd message to protocol signal level. This circuit and details are provided on the data sheet of elm327 which is available from the link given below.


ELM 327

Let us see how we can get RPM value through ELM327. We have to provide 01 0C (Mode 01, PID 0C) command to get engine rpm from vehicle. Here 01 and 0C are in hex format. Elm 327 accepts and reply only in ascii format. So we have to provide the command in ascii format to the UART port. Now we should send ‘0’(ascii value of 0) ‘1’(ascii value of 1) ‘0’(ascii value of 0) ‘C’ (ascii value of C). After sending these 4 ascii characters we must send a carriage return (0x0D) to indicate the command is over.

After getting the command, ELM327 converts the command to protocol frame format and send to the obd port. Obd reply mesage from obd port is converted into ascii format and it is send out through UART port. Developer doesn’t have to bother about the internal conversions and all. We just give obd commands in ascii format to the uart port and receive the obd reply in ascii format ! It is as simple as that :-)

Suppose we have received the reply as ‘4’ ‘1’ ‘0’ ‘C’ ‘2’ ‘A’ ‘0’ ‘7’ with a carriage return.
Now we have to convert this ascii value to hex format before processing. Now convert ‘4’ ‘1’to 0x41, ‘0’ ‘C’ to 0x0C, ‘2”A’ to 0x2A and ‘0’ ‘7’ to 0x07
reply message : 0x41 0x0C 0x2A 0x07
0x41 indicates command success
0x0C indicates pid is for engine rpm
A = 0x2A = 42(dec)
B = 0x07 = 7(dec)
applying formula , rpm = ( ( A * 256 ) + B ) / 4 m = ( ( A * 256 ) + B ) / 4
rpm = ((42 * 256) + 7) / 4 = 2689.75

Before issuing obd commands to ELM327, we need to set some configurations in it. As I already mentioned, these configurations can be done through AT commands. Full details of AT commands is given in the data sheet. Here I am trying to explain some necssary commands for ELM327 to make a simple obd scanner. We should send a carriage return after the command to indicate command is completed. Response message also have a carriage return at the end to indicate the end of response message.


This command is used to reset elm327. After reset all the settings goes to its default value and gives response as the name and firmware version of the controller.
Command : ATZ
response : ELM327v1.5


Elm327 supports different protocols. If we want to scan a CAN 11 bit id 250 baud vehicle, then we should set the protocol to CAN 11 bit id 250 baud in ELM327. Here we explicitly set the protocol. ELM327 has option to detect the protocol automatically . If we dont know the protocol of the vehicle, it automatically search and find the protocol by issuing ATSP 0 command.

Command : AT SP 0
response : OK


By issuing AT DP command, it will gives the name of current protocol using.

Command : AT DP
response (eg) : AUTO, ISO 15765-4 (CAN 11/500)
AUTO means, it find the protocol on auto search command(ATSP 0).

More details of these command are given in ELM327 data sheet.

Note: commands other that AT command interpret as OBD commands.

Steps for implementing a simple obd scanner in a micro controller using ELM327


connections elm 327

programming steps

Command should be in ascii format and send carriage return at the end of the command.

1. Set uart of MC with 9600 baud, 8 bit data, 1 stop bit and parity none.

2. It is better to enable uart receve interrupt(optional)

3. Send ATZ command .

4. Check response in receiver buffer(ELM327 v1.5)

5. If the response is correct, then issue a AT SP 0 command

6. Check response. If response is OK, go forward

7. Send obd command for pid support (01 00)

8. Here we should wait some more times because it is in auto search mode(it has to search protocol one by one untill get a valid one). It is better to provide minimum (3 sec) delay

8. Check the success code of the received data(‘4’ ‘1’)

9. If the command is success, we have to convert the ascii received data to hex value, then only process the data. Here we get the informations of supported pids.

10. Now we can issue AT DP command to know the protocol it found. ( There is no use to provide AT DP command immediately after ATSP 0 command. we must provide a obd request command in betwen these two commands then only it searches the protocol ).Here we have basic informations about supported pid’s and the protocol.

12. Now onwards we can request the value of sensors by providing appropriate obd commands.
Send command, check success code, convert data from ascii to hex, use processing formula to calculate the value. It is very simple !


Thank you for patiently reading this lenghthy blog.Hope it gave you some useful ideas about working with ELM327 or compatible chips to implement OBD related stuff.

BTW if you are planning to outsource OBD related product development, please check us out ! We have developed several hardwares as well as written thousands of lines of code for OBD related stuff ! So we won’t dissapoint you if you choose us to work with :-)

Leave a Reply