Go Down

Topic: OBD II Bike Connector - Pass via bluetooth (Read 89553 times) previous topic - next topic



I´d like to receive diagnostic data from my motorcycle (Kawasaki Z750r - 2012).
The first challenge is, that against all cars and trucks, the diagnostic interface is not standardized on two wheels.
Neither the plug, nor the communication.

That´s why I cannot use a cheap (china) OBD II to Bluetooth adapter.

I´m familiar how to communicate via K-LINE of KDS Bus, from here. In my case KWP2000 (ISO-14230).

What I´d like to do:
Contrary the most solutions here (or the most famous OBDuino), I want to pass the data via Bluetooth, not receiving it.
My receiver is a Gamin Virb XE Action-Cam. It stores the information according to a video, and display them later on, as some nice gauges.

Step two will be an additional, small display to show current gear and some infos, at present I don´t know :)

The Virb XE action cam already has GPS, gyro sensors and stores the data onto a microSD card.
It comes with a OBD 2 compatible bluetooth connection.
Thats why I am searching for a lightweight solution.

There are lots of (more or less) expensive OBD Boards. But none of them fulfilled my wishes.

What do I have:
  • Arduino Uno / Arduino Mega - should be replaced later
  • E-L9637D - Regulates the RS323 (RX & TX) Signal down from 12V to ~4V
  • TSR 1-2450 24 V/DC 5 V/DC 1 A 6 W - Reduces Voltage from 12V to 5V
  • Bluetooth receiver / recorder (aka Virb XE)

What do I need:
  • Arduino Nano, BlendMicro or similar (included Bluetooth?)
  • Bluetooth-Shield (unless already included)
  • Waterproof LCD Display - Step II
  • Waterproof case - Step II


Which board would you suggest?
The space blow my seat is really restricted. It should be powerful enough to transmit several information at once. In the best case, it already has Bluetooth.
Will it work with the L9637D?
The description says it can handle ISO 9141 and I need 14230.
How to submit the signal to the receiver? It seems that the Virb XE uses the same protocol (ELM327) as the OBD II Bluetooth adapters are using. Also the famous Torque App communicates by that. Maybe someone has already forwarded diagnostic data.

Maybe you´ve got any further suggestions or Ideas.


Jul 22, 2015, 02:31 pm Last Edit: Jul 22, 2015, 02:36 pm by Trib
A small update:

The partially above mentioned items (E-L9637D & Virb XE-Camera) arrived. Also some wires, 12V switch, SOIC Board (to solder Lxxx SMD on it), ect.

And I just bought some stuff to finally begin with the project.

At first I wanted to start with my old UNO, but to implement the bluetooth part, its necessary to have a BT device :)

My next steps will be (dependent on what arrives first):
  • Soldering SMD to socket
  • Soldering LCD (long waterproof cable to place it into the cockpit later on)
  • Create Sketch from several tutorials*
  • Create DotNet Test-Application to connect to the Arduino by USB (Serial) and afterwards by Bluetooth
  • Measure voltages & pin assignment on diagnostic interface
  • Measure voltages after L9637D
  • Connect everything on a breadboard
  • Testing, optimizing, testing, optimizing, and begin right from the start
  • Soldering everything up
  • Creating waterproof case (Board & Display)
  • Laying wires under the fueltank
  • Take a ride with my Action Cam

*My most influential Tutorials:
KDS Protocol Kawasaki
OBD 2 LCD Sketch
ELM327 Commands PDF
OBDuino Wiki
OBD Explaination (German)
LCD wiring
Getting started with Blend Micro

That´s pretty much everything I/you need and a bit more :)


Nov 04, 2015, 01:51 pm Last Edit: Nov 04, 2015, 02:00 pm by Trib Reason: Including Images
A huge update:

It´s nearly done! There´ve been several challenges, but it finally works :)

  • Arduino Nano
  • HC-06 Bluetooth
  • L9637D
  • Ceramic-Capacitor 10 nF 50 V/DC
  • 510Ohm Resistor

Also several different displays, to test. At least I´ve ordered a 128x64 OLED from AdaFruit 0,98".

There are a lot of wiring schematics around. But it´s only important to connect Rx to Rx and Tx to Tx (not twisted!) and use a pullup-resistor to the K-Line (connect K-line with VIN from diagnostic by ~510-550Ohm)
Important: Unconnect Rx if you want to upload your Sketch!

This has to be splitted into several smaller pieces of work.

OBD II compatible Bluetooth dongles all work with a ELM327 chip (or a china-clone).
This adapters are used by AT-Commands, which setup the communication protocol. Afterwards the Protocol ID´s were submitted in Hex-values as text.

The cmd´s begin with "AT" + command [+ Value] + '\r'

ATL0\r - means tunrning Linefeed (\n - 10) off (That does NOT mean, turn CarriageRetrurn | \r - 13 off)!
You have to return: OK\r>\r
The > is a prompt, which completes a command-set. Exceptions where: Unknown Cmds ? or Device Info.
Important for my Action Cam: The answer to ATZ (Reset) must contain the Version. F.e. "ELM327 v1.4". Otherwise the cam will not proceed.

DSet to default (Header = false, spaces = false, ect)
ZReset Device
H0 / 1turn Header on or off
IDevice Info (ELM Version)
SPProtocol Auto
S0 / 1turn spaces on or off
L0 / 1turn linefeed on or off
E0 / 1turn Echo on or off
M0 / 1use memory (store last CMD)

PID Lists:
There are every 32 bits lists of the following 32 specified bits:


The response is not completed with OK. Only newline and Prompt (>)!
What does it mean?
Take all PID´s from 01 - 20 (32pcs). 00 is reserved for the first PID-List, 20 is the next one.
Now convert the response from 00-request to bits:

181B8001 (ignore 41 [Response is valid] and 00 [Request])

Now you can lay it over your PID-list and see which PID is valid 1 or not supported 0.

My personal challenge was to translate the OBD2 PID´s to the appropriate KDS PID (Kawasaki Diagnostic System). And afterwards to calculate the response to the required format.

Sending Data:
Now you will receive the register and can put the answer through. (Torque-App will ignore the valid PID´s and you will have to return "NO DATA", Garmin Virb-Cam suits to the valid values)
01 (Show current data) + 0C (PID) + \r [sometimes a space only. Don´t really know why]
Remember to answer properly:
XX-Requested PID, YY-Value (can also be longer)

Now one of the most interesting part!
I´ve made usage of a code from Tom Mitchell (Kawaduino)
You can get it from BitBucket and see the result on YouTube.

The most important parts are the FastInit()-Function to start communication and diagnostic mode.
And the sendRequest()-Method to create & send the request and receive the response, unpack it and check the checksum.

It was a hard way to get the hardware work (wrong Bluetooth-module, broken E-L9637D, Pulldown instead of Pullup resistor...).
The software was also very time consuming. To check the Arduino Sketch, I created a ECU-Emulator in C#. It answers requests with configurable responses.
Then I created a Bluetooth-Sniffer to receive what kind of information the Camera or Torque-App requests and how I have to respond.
At least I made a ECU-Sniffer, which requests all supported PIDs from my motorcycle.

When it all worked, the next task was to find out which PID correspond to which sensor. The ECU-Hacking Board (link in my second post) just got knowledge of Speed, RPM, Temp, Battery  and Gear. By try and error and some help from a guy with a diagnostic device, I was able to find out about 33 known PIDs. Another 27 are still open.

My further investigations are to find out some calculations, how to use throttle or throttle valve.
After that, I´d like to upload all my code to GitHub. Including:
  • ECU-Emulator (Windows Application)
  • ECU-Sniffer (Sketch)
  • Bluetooth-Sniffer (Sketch)
  • ECU-Reader (Sketch) -> The result :)
  • Valid PID-List with formula, etc. (Excel Sheet)

As you can see in the attached pictures:

The finished Arduino Nano:

Test on my bike:

ECU-Emulator with Ardu connected:

My first ride :)

(Garmin Virb XE Action-Cam)


It still is not ready, but working.
Who ever is interested can find the code here:

GitHub - KDS 2 Bluetooth

Including my working solution, a .Net ECU Emulator and a Bluetooth-Sniffer to identify the AT Commands.

I´m sure it can be optimized a lot. If you got some hints, please let me know :)


It still is not ready, but working.
Who ever is interested can find the code here:

GitHub - KDS 2 Bluetooth

Including my working solution, a .Net ECU Emulator and a Bluetooth-Sniffer to identify the AT Commands.

I´m sure it can be optimized a lot. If you got some hints, please let me know :)
AMAZING!! You just did what I've been preparing to do on my Z800 :)

Thanks for sharing the information, it helps a lot a lot a lot.


You are welcome!

The final result looks like that:

I´ve adopted the idea of combining that with a display. It would be way to slow.
Maybe it will be another project :)
There are some possibilities to read the value directly from the tachometer (CAN-Bus).


You are welcome!

The final result looks like that:

I´ve adopted the idea of combining that with a display. It would be way to slow.
Maybe it will be another project :)
There are some possibilities to read the value directly from the tachometer (CAN-Bus).
Good job!!! Thanks for shared information!!!

Sorry but I'am noob about this type of comunications.

Knowing all of it, there is a possibility to configure an ELM327 interface to conect directly to ECU, I have tried, but with no success!

Thanks again!!!


Hi rmachiavel,

no I dont think that´s possible. An ELM327 is created for an OBD II Interface, which bikes don´t have.
The communication of OBD is made by two wires (Serial), f.e. KDS has one wire (K-Line). The ELM has also a K-Line, but as fas as I know only for manufacturer specific things. Not Diagnostic.
It has a specific initialization procedure and an own set of Service ID´s. An example: Read current Data: OBD 01, KDS 21.
On the top of it, the PID´s which are requesting the specific values, are completely different. RPM 0C in OBD and 09 in KDS. Also the response has a different length and calculation.

So you´d need a L9637D-Chip to change Serial to K-Line. Then you have to find out how to change the Init-Sequence to wakeup the ECU (ELM do not have KWP2000 (ISO-14230), its a gambling to find a similar one). The device, which is connected to the ELM327 has to translate all ServiceID´s and PID´s. The calculations are different, so this has to be fixed also.
Last but not least, the PID-Lists have to be manipulated to the translated ones.
That means (if the init works) you have to write a software from the scratch to communicate with the ELM327 and fake & translate all that values.

All of that is done by my project, pretending to be a real ELM327.


Thanks a lot!!!!

Saved me a lot of time! I´ve have tried a lot with ELM327, because I can´t find the L9637 in Brazil and the ELM have a interface that seems to be similar, but is not. So I bought the IC from ebay yesterday, so I will wait it arrive to continue with project. Thanks again!!!

Best Regards!


Great. I can't believe that I miss this topic up to now. Have a karma. +1
Arduino clone with ATmega1284P   http://forum.arduino.cc/index.php?topic=277260.0


I´ve updated the code on GitHub.
There have been some precision problems, which are solved now.
Also as announced, I removed the LCD part.
Some AT-Commands where added to fit to more OBD-Apps.

Then I began to "Sniff" some diagnostic stuff like Error-Codes and how to clear them. But currently I´m in the middle of investigating and testing it. It will take some more time.

During that, I came to a big limitation of sending and receiving messages. Everything was created for a specific Mode and ServiceId. So I started to rewrite that also.
KWP2000 is a precursor of Unified Diagnostic Services, which helps what is possible and which ServiceID´s are available.

The whole code will be rewritten more clean and flexible, then.


Jul 05, 2016, 02:01 pm Last Edit: Jul 05, 2016, 02:07 pm by Scissor
I've also been busy to connect an Arduino to my motorcycle (Kawasaki Z750 2004), I'd like to thank you a lot for your effort. Especially determining the conversion formulas to get actual engineering units is really useful. I put together this basic library for the KDS serial communication which you can find on my Github, which you might find useful.

Did you try to request localidentifier 0xBF? I get a large response message of 72 bytes (including headers and checksum), which might contain interesting data.


Hi Scissor,
you are welcome! I´m glad to find more and more combatants.
The list of known PID´s is far from being complete, maybe we will get further with some people :)

Many PID´s base on try & error, some where collated with a 3rd-party diagnostic device. Hard enough to calculate the values to a meaningful result, even harder to make it OBD II understandable :D

I´ve not investigated 0xBF. Is it officially supported by '04 Z? As you can see in my Excel-Sheet, its not part of my PID-List.
There are diagnostic functions, which are sending more frames at once (f.e. freezed data) or constantly (for exhaust testing purposes). I´ll try that, after I raised my buffer to such a huge value :-O

If you´d like to, run my SniffEcu()-Method and send me your results, we will have '04 Z750, '12 Z750r & '14 Z1000 results.

There are many things to investigate. Likewise ECU-ID, which is 1A without a ServiceID. I´m sure, there is a lot more! Currently I search for trouble-codes SID 0x13 and freezed Data SID 0x12. Not very easy without a failure ;)

You are theoretically able to down- and upload even the ECU firmware :)


Thank you. I understand it's difficult to obtain those conversion formulas, I guess they're mostly similar to the formulas for the Suzuki Diagnostic System (SDS). Unfortunately only very few are made public so far.

I made a simple datalogger which I used to find available PIDs (I call them localidentifiers, as in the ISO documents). So far I ran the datalogger from localidentifier 0x00 to 0xFF. I've listed the results in an excel file and it looks very similar to your results, I will post them here shortly.

One remarkable thing is that localidentifier 0xDB does not return anything, not even a negative response message. From the ISO-14230 documents:

0x00 - reservedByDocument
0x01 - localIdentifierScalingTable
0x02-0xEF - localIdentifier
0xF0-0xF9 - dynamicallyDefinedLocalIdentifier
0xFA-0xFE - systemSupplierSpecific
0xFF - reservedByDocument
Hence I expect that the most standard sensor data should be in the 0x02-0xEF range. Unfortunately the 0x01 request does not return the scaling table which would reveal all conversion formulas.

In your excel sheet you mention "Supported PIDs" several times. I don't really understand how you obtain the available localIdentifiers based on that response message. At first I thought it just might be a bitmask i.e. convert the HEX values to bits, and assume every "1" corresponds to an available localIdentifier. However this does not correspond to the results I get.

There are many more things we might try e.g. periodic transmission and  dynamicallyDefinedLocalIdentifier to construct a localIdentifier, with this a much higher data rate could possibly be reached.

I also tried once to request all DTCs, but without luck. I might have done something wrong, so I can try again soon.

Indeed, at some point we can decide to use the upload and download functions described in the ISO-14230 document. However, I expect it is a rather delicate process which can easily screw up the ECU if something fails during data transmission.

Go Up