Arduino OBD2 Simulator




Ive been building an Arduino OBD2 Scanner to interface with my Jeep's OBD2 port, but it became a beeeeeg! schlep to upload code to my Arduino Nano + 16x2 LCD + ELM327 Scanner device, then haul the whole prototype to the Jeep in the gurage the whole time and then only to find there was something small i forgot to change.

I needed to find a way to test my prototype in the comfort of my home.

Ive searched high and low and couldn't find any Arduino OBD2 simulators that i can build my self. I came across one or two websites that's making use of Arduino to build an OBD2 Simulator but they dont give you the code you have to buy the ready made product from them, I.E the FreeMatics for something like a whopping $169, Wheres the love for Open source in that ???? pffft! I dont see $169 I see about 8 Arduinos i can buy with it.

So unfortunatly and fortunatly for you :-) I had to figure out how i'm going to build one my self, which forced me to now focus on a project i had to take on in order to complete my initial project, Took me some time to figure out how to send PIDs in standard OBD2 format. But at the end i could connect a FreeObd Scanner program which you normally get with your ELM327 Scanner.

Stuff you need.

Arduino UNO

CAN-BUS Shield

ELM327 (USB,Bluetooth,Wifi) It doesnt matter which flavour you have. As long as it creates a com port

OBD2 Diagnostics software (Just to Test if it works) any OBD2 software should work, the software you got with the ELM327 scanner should do just fine.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Step 1: the Code

Unfortunately for this to work you MUST have a Shield from SeeedStudio Called the CAN-BUS Shield. You also get one from Skpang but the code below will not work for Skpang unless you alter it slightly.

If you dont know already you also need the SeeedStudion CAN-BUS Library loaded int he Arduino IDE.

Upload the below code, if you dont have the CAN-BUS Shield library loaded the below will most probably error out.

//This Arduino UNO Sketch requires the Seeed CAN-BUS Shield Libraries
// #include #include "mcp_can.h"
INT32U canId = 0x000;
//2024    4    65    12    18    248    185    147
unsigned char len = 0;
unsigned char buf[8];
char str[20];
String BuildMessage="";
int MSGIdentifier=0;
void setup()
    if(CAN_OK == CAN.begin(CAN_500KBPS))
        Serial.println("CAN BUS Shield init ok!");
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        goto START_INIT;
void loop()
    char rndCoolantTemp=random(1,200);
    char rndRPM=random(1,55);
    char rndSpeed=random(0,255);
    char rndIAT=random(0,255);
    char rndMAF=random(0,255);
    char rndAmbientAirTemp=random(0,200);
    char rndCAT1Temp=random(1,55);
    unsigned char SupportedPID[8] =       {1,2,3,4,5,6,7,8};
    unsigned char MilCleared[7] =         {4, 65, 63, 34, 224, 185, 147}; 
    unsigned char CoolantTemp[7] =        {4, 65, 5, rndCoolantTemp, 0, 185, 147};  
    unsigned char rpm[7] =                {4, 65, 12, rndRPM, 224, 185, 147};
    unsigned char vspeed[7] =             {4, 65, 13, rndSpeed, 224, 185, 147};
    unsigned char IATSensor[7] =          {4, 65, 15, rndIAT, 0, 185, 147};
    unsigned char MAFSensor[7] =          {4, 65, 16, rndMAF, 0, 185, 147};
    unsigned char AmbientAirTemp[7] =     {4, 65, 70, rndAmbientAirTemp, 0, 185, 147};
    unsigned char CAT1Temp[7] =           {4, 65, 60, rndCAT1Temp, 224, 185, 147};
    unsigned char CAT2Temp[7] =           {4, 65, 61, rndCAT1Temp, 224, 185, 147};
    unsigned char CAT3Temp[7] =           {4, 65, 62, rndCAT1Temp, 224, 185, 147};
    unsigned char CAT4Temp[7] =           {4, 65, 63, rndCAT1Temp, 224, 185, 147};
    if(CAN_MSGAVAIL == CAN.checkReceive())  
      CAN.readMsgBuf(&len, buf); 
        canId = CAN.getCanId();
        for(int i = 0; i

Step 2: Step 2: Preparing the ELM327 Scanner Cable to Test Your New OBDII Simulator.

You can do it which ever way you like. since the ELM327 Scanner cable is quite cheap i modified it to my liking.

I removed the original sticker to get to the 4 screws to open the box, I took a male to female extender USB cable and cut it in half.

and soldered the one piece of the USB cable's end to pin 6-CAN High and Pin 14-CAN Low, made a little hole on the side, closed it up and stuck a sticker on the side to remind me which is which. Look at the photo's

I then terminated the other half of the USB extender cable to the SeeedStudio Can-BUS shield, Obviously CAN-H from ELM327 to CAN-H on the Shield and same with the CAN-L wires.

Step 3: Step 3: the Testing.

I then powered up the Arduino, The Arduino+CANBUS Shield is now stand alone and doesnt need a pc but i just left it connected to get power from the USB port.

Then connectr the ELM327 to USB, in the device manager make sure which comport belongs to the ELM327 double check because you now have 2 com ports the Arduino's COM Port and the ELM327.

Start an OBD diagnostics windows program I.E then let it monitor the RPM.

The OBD Simulator isnt smooth because its programmed to randomly generate "Valid" data I.E the RPM wil randomly jump from say 5RPM to 800RPM to 20RPM to 1800RPM ect ect, Ive made notes in the Arduino code, its easily readable and doesnt support all PID data but you can certainly add to it. By looking at some of the standard PIDs from Wiki and following "My" methodology

You can also if you want build it into a box then add a few buttons to alter the variables assigned to the random generator function, I didnt need smooth values, Just as long as i'm able to test my Arduino ScanTool Prototype.

Be the First to Share


    • Made with Math Contest

      Made with Math Contest
    • Multi-Discipline Contest

      Multi-Discipline Contest
    • Robotics Contest

      Robotics Contest

    34 Discussions


    16 days ago

    If anyone is getting INIT failed simply set SPI_CS_PIN = 9 instead of 10 for the input param MCP_CAN CAN(SPI_CS_PIN);


    4 weeks ago

    In seeedstudio WebSite i found can-bus V1.2 and V2.0. Would you have any preference? Both worked perfectly?

    1 reply

    Reply 16 days ago

    I ordered V2.0, the code seems to load on my device but I can't INIT, it seems to be failing for some reason.


    3 years ago

    Hi mviljoen2,

    Like your simulator, instructables code renderer breaks your example. Could you repost your arduino code again or put the .ino file in a zip? Thx

    4 replies

    Reply 3 years ago

    found your code on a forum post. Put it in a github repo to extend it.


    Reply 7 months ago

    I am very new to this field. I tried to open the program in Arduino IDE. Upon verification it is giving many errors which I am new and can't figure out.
    Arduino: 1.8.9 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
    Seeedlib-ecu-sim:6:1: error: 'INT32U' does not name a type
    INT32U canId = 0x000;
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino: In function 'void loop()':
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:49:81: warning: narrowing conversion of 'rndCoolantTemp' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char CoolantTemp[7] = {4, 65, 5, rndCoolantTemp, 0, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:50:76: warning: narrowing conversion of 'rndRPM' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char rpm[7] = {4, 65, 12, rndRPM, 224, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:51:78: warning: narrowing conversion of 'rndSpeed' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char vspeed[7] = {4, 65, 13, rndSpeed, 224, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:52:74: warning: narrowing conversion of 'rndIAT' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char IATSensor[7] = {4, 65, 15, rndIAT, 0, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:53:74: warning: narrowing conversion of 'rndMAF' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char MAFSensor[7] = {4, 65, 16, rndMAF, 0, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:54:85: warning: narrowing conversion of 'rndAmbientAirTemp' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char AmbientAirTemp[7] = {4, 65, 70, rndAmbientAirTemp, 0, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:55:81: warning: narrowing conversion of 'rndCAT1Temp' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char CAT1Temp[7] = {4, 65, 60, rndCAT1Temp, 224, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:56:81: warning: narrowing conversion of 'rndCAT1Temp' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char CAT2Temp[7] = {4, 65, 61, rndCAT1Temp, 224, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:57:81: warning: narrowing conversion of 'rndCAT1Temp' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char CAT3Temp[7] = {4, 65, 62, rndCAT1Temp, 224, 185, 147};
    C:\Users\swanand\Documents\Arduino\ecu-can-bus-simulator-master\Seeedlib-ecu-sim\Seeedlib-ecu-sim.ino:58:81: warning: narrowing conversion of 'rndCAT1Temp' from 'char' to 'unsigned char' inside { } [-Wnarrowing]
    unsigned char CAT4Temp[7] = {4, 65, 63, rndCAT1Temp, 224, 185, 147};
    Seeedlib-ecu-sim:64:9: error: 'canId' was not declared in this scope
    canId = CAN.getCanId();
    exit status 1
    'INT32U' does not name a type
    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

    Will you please guide me about what is to be done.

    Reply 16 days ago

    Hi swanand_g, I'm late to the party but to fix your issue simply add the line below to the top of your file.

    #define INT32U unsigned char


    Reply 3 years ago

    Thanks cinezaster :-) , that's very helpful, apology for only replying now, I somehow missed your previous message.


    Question 4 months ago on Step 2

    For connecting the ODB2 adapter to the seeed-shield, did you have to inject some voltage on the L/H pins as well? Because I tried to reproduce your steps (with 2 different modules) and neither of them gave any output when connected this way (e.g. would not respond to commands like ATZ).


    Question 1 year ago on Step 3

    So, lets start at the beginning.

    I want to build a scratch built car ... I built my first street legal
    dune buggy when I was 14 ... I just turned 56 and wanted an "updated"
    version (thinking a custom front end and moving a Honda front wheel drive to
    the back ... or something like this .... use a simple carburetorand vacuum advance ... just a toy so keep it

    Here in VT, this would be considered a "scratch built"
    car.I checked with the DMV, they gave
    me a list of requirements for the body (bumpers, tires, windshield, defroster ......)
    and they gave me paperwork to request a VIN since it would be considered a
    "new" vehicle.

    So far, so good.

    Now the problem ... they require all vehicles ... even scratch built
    ones ... to have an OBD II system!They
    access this on a yearly basis to pass inspection.

    I talked with the DMV, they said yes it is a requirement but they did
    tell me I should talk with the Department of Environmental Conservation, Air
    quality division.They said they could
    not understand why it was a requirement and that they would even write a letter
    saying this.Their best guess was that
    someone was covering their "butt" just in case it was a federal
    requirement.I went back tot he DMV but
    was told "we are not about to change the regulations for one person"
    and there is no provisions in the regulations for an exemption.

    Now the funny part, when I asked about having to meet emission (since
    say I registered the car this year, I would expect it would need to meet 2018
    emission standards) they said no.It
    just must report that all systems that are installed are "ready",
    that the mil light works properly and that there is no error codes.

    I went through all the regulations.They have two paragraphs on making sure the MIL light is working (they
    obviously don't trust that someone has just taken out the bulb).They actually plug in a scanner to make sure
    there is no error codes.

    They also mention making sure all systems are "ready" as
    opposed to "not ready" of you will fail the test.

    The DMV manual mentions there are 11 items that are checked ... though
    they do say that not all vehicles have all 11 (some will say "not
    available" or "not supported").

    So, I have my hands full.

    Now I have a million questions ... lets start with just a couple of the

    1) What are the 11 items they are monitoring?

    2) Can I do this with this shield or is there an aftermarket simulator that anyone recommends that has a
    MIL light output and can take in a few sensors?

    In other words, lets say I want to monitor a few of the 11 items (and
    maybe a few others).Lets say I use an
    oxygen sensor.It would be great to have
    this tied into the simulator and give out real time data.I may program a very high limit so that it
    never gives an error code but at least I could show it is monitoring and that
    if I unplug it then it would give an error code.

    Again, I am not sure what the 11 items are but I could tie in RPM's,
    temperature, ..... maybe even a knock sensor (I have no idea how these work but
    it would be nice to have my spark retard if it senses knock), .....

    Electronics is my hobby and I have a background in industrial
    instrumentation so I think this might be doable but I really don't know
    anything about OBD II ... except how to plug in my scanner and find out why my
    MIL light is on.

    Any advice please would be grealy wecome!

    Thanks so much..... Mike


    2 years ago

    Can you suggest an App to use with the ELM device? Those I´ve tried don´t let me conect, looks like the protocol is not recognized.


    2 years ago

    I have follow the instructions but I receive only CAN_NOMSG (4), status from Arduino. Looks like the shield isn´t sending any message to OBS reader, and in fact the RX and TX didn´t blink, I´ve tested with other program and the shield looks fine. What should be wrong?


    2 years ago

    Has anyone managed to get this working with a bluetooth elm327 scan interface?

    Julio J.B

    2 years ago

    Hi, what shield version are you using? 1.0 o 1.2? It will work with both versions? Thanks in advance!


    4 years ago on Introduction

    Hmmm, this comes close to what i'm trying to accomplish...
    I have an arduino Ethernet setup in our tugboats engine room, its an old slow running diesel engine w/o obd.
    The arduino has sensors for measuring the engine's rpm, oil pressures, coolant temp etc, and it serves this data on a webpage for the moment.
    Next step is to create a virtual dashboard with DashXL from Palmer Performance, to do so i would have to make the arduino pour the measurements into OBD format and pipe the data from the network to a virtual serial port.
    Is this doable ? Any suggestions on how to approach this project ?

    2 replies

    Reply 3 years ago

    Just a quick question, im looking to make exactly whst youve described. Were you succesful with your design? Im looking into a track data ligger (harrys lap timer) for a sprint car!


    Reply 4 years ago on Introduction

    Hi Eric, Thanks for the comment, Its definitely doable.
    I dont know dashXL at all but quickly looking at it I noticed it can do OBD2 Stuff, do you know the Torque Smartphone App ?, You are able to add customizable PIDs, If you are able to do the same in DashXL and If your tugboat has sensors which is outside of the normal OBD2 Type sensors you could easily just create an "eOBD2" PID as in extended OBD2 which is common on some vehicles I.E My Jeep also has a Transmission Temp sensor but is not part of the usual OBD2 spec, but you are able to add it into Torque Pro by supplying the PID and the message value, So what you should do is look at then use a PID which is not already used and have the Arduino Simulate the data in OBD2 format using you own PID chosen which .

    I'm sure most of the PIDs you need is already available in the standard OBD2 spec.
    In the OBD2 Wiki link i posted it also gives you the formula on how to calculate the PID's IE if you have a temp sensor you would supply it in format by adding 40 to the real value, an OBD reader will then take the value and subtract 40 again as per the spec

    Catch my drift ?,
    You have quite a nice project ahead!, sounds interesting.


    3 years ago

    Hi mviljoen2, Thanks to your post I was able to build and run the simulator.

    Using your code I'm able to simulate different sensor values but I'm also interested in simulating DTC's. Could you please guide on how this could done? This link describes that in mode3 set DTC's are returned but i'm unable to figure out how to set the DTCs in this simulator. Any suggestions would be very helpful.



    4 years ago on Step 1

    Hi there! It seems that your code is incomplete, as shown by the lack of sending the data you create, and the incomplete for loop. I could really use this code. Could you upload the missing pieces please? Thank you!