Bike interface OBD

seems that the delay of 10ms between two bytes is not needed

#define debug Serial
#define bike Serial1
#define TX_PIN 18
byte message0[] = {0xFE, 0x04, 0xFF, 0xFF};
byte message1[] = {0x72, 0x05, 0x00, 0xF0, 0x99};

void setup()
{
  debug.begin(115200);
}

void loop()
{
  char incomingCommand = 0;
  while (debug.available() > 0)
  {
    incomingCommand = debug.read();
    debug.print("\nCommand: ");
    debug.println(incomingCommand);
  }

  if (incomingCommand == 'S')
  {
    initHonda();
  }
  checkResponse();
}

void checkResponse()
{
  while (bike.available() > 0)
  {
    byte incomingByte = bike.read();
    debug.print(incomingByte, HEX);
    debug.print(' ');
  }
}

void initHonda()
{
  debug.println("Starting sequence");
  bike.end();
  pinMode(TX_PIN, OUTPUT);

  digitalWrite(TX_PIN, LOW);
  delay(70);

  digitalWrite(TX_PIN, HIGH);
  delay(120);

  bike.begin(10400);

  sendRequest(message0, sizeof(message0));
  // No response is expected

  // wait 25ms and avoid echo
  debug.print("Echo: ");
  uint32_t start_time = millis();
  while (start_time + 25 > millis())
  {
    checkResponse();
  }

  sendRequest(message1, sizeof(message1));
  // respond: 02 04 00 FA
  debug.println("\nWaiting response");
}

void sendRequest(uint8_t request[], uint8_t len)
{
  for (uint8_t i = 0; i < len; i++)
  {
    bike.write(request[i]);
  }
  bike.flush(); // wait to send all
}

if this doesn't work the problem is in the wiring, please could you post some pictures and a schematics?

aster94:
seems that the delay of 10ms between two bytes is not needed

#define debug Serial

#define bike Serial1
#define TX_PIN 18
byte message0[] = {0xFE, 0x04, 0xFF, 0xFF};
byte message1[] = {0x72, 0x05, 0x00, 0xF0, 0x99};

void setup()
{
 debug.begin(115200);
}

void loop()
{
 char incomingCommand = 0;
 while (debug.available() > 0)
 {
   incomingCommand = debug.read();
   debug.print("\nCommand: ");
   debug.println(incomingCommand);
 }

if (incomingCommand == 'S')
 {
   initHonda();
 }
 checkResponse();
}

void checkResponse()
{
 while (bike.available() > 0)
 {
   byte incomingByte = bike.read();
   debug.print(incomingByte, HEX);
   debug.print(' ');
 }
}

void initHonda()
{
 debug.println("Starting sequence");
 bike.end();
 pinMode(TX_PIN, OUTPUT);

digitalWrite(TX_PIN, LOW);
 delay(70);

digitalWrite(TX_PIN, HIGH);
 delay(120);

bike.begin(10400);

sendRequest(message0, sizeof(message0));
 // No response is expected

// wait 25ms and avoid echo
 debug.print("Echo: ");
 uint32_t start_time = millis();
 while (start_time + 25 > millis())
 {
   checkResponse();
 }

sendRequest(message1, sizeof(message1));
 // respond: 02 04 00 FA
 debug.println("\nWaiting response");
}

void sendRequest(uint8_t request[], uint8_t len)
{
 for (uint8_t i = 0; i < len; i++)
 {
   bike.write(request[i]);
 }
 bike.flush(); // wait to send all
}




if this doesn't work the problem is in the wiring, please could you post some pictures and a schematics?

No Luck. I got the same response as before:

09:11:34.417 -> Command: S
09:11:34.417 -> 
09:11:34.417 -> Starting sequence
09:11:34.619 -> Echo: F8 0 FF 
09:11:34.653 -> Waiting response
09:11:34.653 -> 0 0

Here's an album with pictures:
https://imgur.com/a/sWckoxa
Let me know if I can clarify anything with more pics.

1 Like

Seems to be correct, a few question just to be sure:
The ground of the arduino board and the motorbike are connected?
The arduino tx go to the L9636 tx? (them don t have to be swapped)
Are you sure the L9636 is in the right position? The position of pin 1 is decided by this little line
https://postimg.cc/bd7471rj

If all of this are correct we should wait for the logic analyzer and then put a voltage divide to the k-line and check it

By the way in the future I suggest you to use adapters like these for the not-DIP packages, i bought a few of these with various size and them are perfect
https://images.app.goo.gl/FDRybwevtFbtuHGN6

aster94:
Seems to be correct, a few question just to be sure:
The ground of the arduino board and the motorbike are connected?
The arduino tx go to the L9636 tx? (them don t have to be swapped)
Are you sure the L9636 is in the right position? The position of pin 1 is decided by this little line
https://postimg.cc/bd7471rj

If all of this are correct we should wait for the logic analyzer and then put a voltage divide to the k-line and check it

By the way in the future I suggest you to use adapters like these for the not-DIP packages, i bought a few of these with various size and them are perfect
https://images.app.goo.gl/FDRybwevtFbtuHGN6

Thanks for your reply.
The ground of the motorbike is connected to the second black cable seen here (yellow arrows) Imgur: The magic of the Internet.
I checked the TX and RX, they are not swapped.
I'm 99% positive the L9637D is in the correct position - It's not a L9636 chip though, it's the 9637D. Do you think this is a problem? I think this chip was recommended to me elsewhere.
I've already ordered some SOIC to DIP boards from Aliexpress, I hope they will arrive soon (along with the logic analyzer). Im pretty positive this should work. Thanks a lot for your help so far!

It's not a L9636 chip though, it's the 9637D.

it is the same! i didn't wrote the last "D"

Im pretty positive this should work

Me too :slight_smile:

aster94:
it is the same! i didn't wrote the last "D"

Me too :slight_smile:

Alright - the logic level analyzer has arrived! Still waiting on the SOIC to DIP converters though.
Is there something I can already do now that I have the analyzer?

better to wait, meanwhile you could see the schematics here and you should start to find the resisors for the voltage divider to check the k-line (12-14V) with the logic analyzer (max 5V) some value like 10k and 5k would works well

aster94:
better to wait, meanwhile you could see the schematics here and you should start to find the resisors for the voltage divider to check the k-line (12-14V) with the logic analyzer (max 5V) some value like 10k and 5k would works well

I used 10k and 20k - the curiosity just got the better of me and I hooked up the logic analyzer to the bike.
I've attatched the whole analyzer file to the post (used Pulseview), but here is an overview of the interesting parts.
D0 is TX
D1 is RX
D2 is KLine with voltage divider. high was around 4.2 volts.


Pulling K-Line low works well (echo on RX).

Pulling K-Line high after ~70ms

After waiting ~120ms, the sending happens. I think this is where everything is somehow effed:


For some reason, it doesn't get to send the second FF. It should be sending "FE 04 FF FF", but the second FF gets cut off? It also echos F8 FF back right away for some reason. The K-Link also stays low for a long time during sending the 04, and looks like it doesn't react to the sent signals?


Here, it should be sending "72 05 00 F0 99" but it looks like it's sending "78" as the first byte. Maybe the serial isn't ready yet? At other points in time I also got things like "72 02 00 F0 99" and other strange responses.

I assume this confirms that we just need to wait for the SOIC to DIP adapter and that's fine, just wanted to share because I feel this confirms something wrong with my setup.

odb1.zip (960 Bytes)

yes CapFirepants I confirm your thought, there is something not right, it looks like that the kline takes more time than needed to come back to HIGH

in the next days I would write a new sketch then I would suggest two other test:

  1. run it without L9637D connecting the logic analyzer (LA) only to the tx and rx pin of the arduino board
  2. run it with the L9637D but without motorbike (you would need to feed the L9637D VS pin [number 7] with 12v) and with the LA check tx, rx and k-line [pin 6]

then if everything is as expected we could move to the motorbike

I am suggesting these two test because i would like to be sure of the seput before getting to talk with the ECU. I know that this means more work, are you interested anyway in the project?

Hello,

I’ve read both this thread and the thread started by TriB on the KDS system and I have some questions and ultimately am hoping to determine if what I want is possible, followed by some next steps as I’m sure this will be a journey! First I’ll list my bike and current hardware, a bit about myself, then what I want to accomplish followed by what I interpret as being already solved and then a required hardware list. Finally I’ll get into a summary of my questions.

Bike and Hardware:

Bike: 2013 Suzuki GSX-R1000
OBD Reader: OBDLink MX – reads ISO 14230-4 KWP (5 baud init, 10.4 kbaud) and ISO14230-4 KWP (fast init, 10.4 kbaud) (at least in the Android app that it comes with OBDLink)
Android App for Track: RaceChrono Pro
Camera: GoPro Hero5

My skills:

A little about myself – I’m a mechanical engineer with a love for electronics and motorcycles, however have yet to use an Arduino. I’m sure I can pick it up pretty quick as I’ve done a variety of programming in the past and always learned fairly quickly. As for OBD, I worked with Vehicle information a few years ago and analyzed lots of the data logged from OBD readers but always had the calculations performed by the program and didn’t have to program and of the requests myself.

What I want to accomplish:

I would like to create an adapter/unit that takes the k-line data, and processes it for the OBD reader that I have (OBDLink MX) which then would hopefully be able to transmit the data to RaceChrono Pro for overlaying onto my track videos. RaceChrono Pro interacts with the GoPro, external GPS sensors and OBD readers and allows quick and easy video exporting which is why I want to use it.

That being said, as long as it “fakes” the data such that an app like Torque can connect to it and read it like an OBD ELM then maybe it would work fine. The RaceChrono app can connect to any OBD ELM reader. So maybe I need to stick with existing solutions rather than trying to use the OBDLink MX. My only issue is that TriB’s solution has Bluetooth but is KDS and O5i’s is SDS but not Bluetooth.

So what I would like to do is create something similar to what TriB did for the KDS that will output the proper OBD required information to obtain SPEED, RPM, gear position and maybe a few more PIDS such as Oil temp, and coolant temp.

What I believe is solved:

TriB: KDS (Kawasaki) version on GitHub completed, working on an SDS version for Suzuki
O5i: Completed solution for SDS but not bluetooth

What hardware I need:

I’m honestly open to anything at this point as I do not currently own an Arduino so basically let me know which version is the best to get and I’ll go forward with that. I would assume that TriB’s hardware is probably what I need but if there is a better version please let me know:

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

Questions:

  1. Is it possible to get the data to communicate via my OBDLink MX? Or would I be better off going with something similar to TriB’s approach?
    a. Since my OBDLink MX has the K-2000 protocol does that help or simplify anything?

  2. What would be my first step after buying the parts and assembling the circuit?

  3. ECU Sniffing. Do I need to do this or would the results be the same as what you guys have already discovered? If I need to do it I would probably follow TriB’s Sniffer from Github – Does that work for Suzuki’s?
    a. Aster94 (post 69&71) on TriB’s thread has some GSX-R600 2011 pids which I assume would line up to my 2013 GSX-R1000. That being said, I know they can differ greatly from my work experience so I should probably run the sniffer…

  4. TriB - How far did you get with your SDS version? If I can’t use the OBDLink MX then I think yours is exactly what I want to do.

I just spend 3 hours reading the forum posts (and hours before on another night). If I’m not being clear or I’m out to lunch please just let me know!

Thanks,

1 Like

Hello Earendil86,

nice to see that you are full into the topic and trying to get an overview rather then just asking stuff :slight_smile:

First things first:
My current solution (not yet published) is capable of both, KDS and SDS. But some things are not working properly. I hope I can fix that next week on a 4 day racetrack vacation :smiley:

If you go for that hardware design, you can easily convert the values and send them in OBD2 format.

But you can also use the OBDLink MX!
You just have to connect the K-Line, GND and V+. Then you need to reprogram the device via AT Commands, to make it SDS compatible.
Racechrono has a setup for that, where you can enter this commands, and then will be sent to the OBDLink on startup.

Lucky you, I am in a personal conversaton with Antti from racechrono and sent him some testdata, so he can include a conversion interface to make it possible to translate the single dataset from Suzuki into several values.
This will take some time to be included in the next version and I´ll create more data to play around with, next week.

So, I´d reccommend to just create a cable adapter and try that approach first!
I cant, because I only own a cheap china clone ELM327 OBD2 Adapter, which is not capable of being reprogrammed and I think the K-Line is missing.

1 Like

Hey TriB,

Thanks so much for your response! Glad to hear that you’re still working on your KDS and SDS solution. It’s pretty awesome what you’ve been able to accomplish. I’m very jealous of your 4 day racetrack vacation! Stay safe!

As for the hardware vs OBDLink, since there is an option to enter the commands and reprogram the device in OBDLink on startup I’ll test that out! I had found that page long ago but didn’t realize I could use that in the app.

I would like to run my understanding of it by you though.

I assume these are the commands you were linking to:

ATZ
ELM327 v1.5
ATWM8012F1013E (set a special keep alive message)
OK
ATSH8112F1 (set a header for first negotiaton)
OK
ATFI (initialize bus)
BUS INIT: OK
ATSH8012F1 (set a header for data transaction)
OK
1A9A (Read ECU ID)
5A 9A 33 32 39 32 30 2D 30 .....
2108 (Read Data by Local ID)
61 08 0F 02 01 A0 02 02 A0 .....
82 (Close a connection)
C2
ATPC (ELM Protocl Close)
OK

If that’s the case then in RaceChrono Pro I checked and it appears that this goes in the “expert settings” menu under “Initialisation commands” which states, “Enter additional ELM327 initialisation AT commands here, separated by \n. Example: ATSP4\nATIIA13\nATIB96\ATSH8113f1\nATSW00\nATAT2”

Based on that, I assume the text that I would enter would be:

ATZ\nATWM8012F1013E\nATSH8112F1\nATFI\nATSH8012F1\n1A9A\n2108\n82\nATPC

Or do I not need to enter anything after “Set a header for data transaction”? The next few lines are “Read ECU ID” and “Read Data by Local ID” followed by “Close a connection” and “ELM Protocl Close”.
So if not, then I guess this is what I would enter?

ATZ\nATWM8012F1013E\nATSH8112F1\nATFI\nATSH8012F1

Also, once that is entered and I’ve built the cable and connected the OBDLink MX and started RaceChrono what will it give me vs what Antti and you are working on for this “Conversion interface?”.

As an extra note:

For anyone who might be reading, the link in TriB’s post to the data discussed above then links to a posters (kashima’s) schematic for the Suzuki SDS to OBD cable. That image INCORECTLY lists:

SDS MALE SUMITOMO SEALED MT 090 6P #6189-6171 (Male connector)

The actual Suzuki connector to buy is:

SDS MALE SUMITOMO SEALED MT 090 6P #6187-6561 (Male connector)

This is true for at least my bike. I have not yet received the replacement but I can confirm the first one is incorrect.

You´re welcome :slight_smile:

The "Initialisation commands" should be

ATWM8012F1013E\nATSH8112F1\nATFI\nATSH8012F1
  • Set keepalive message
  • Initialize with 0x81 header
  • start communication
  • reset header to 0x80

Anything else is just additional information.

Now, the part is missing, where you can enter a custom PID (0x08) and translate the response to single values, like RPM, speed, etc.
This will definitely be a new feature, but I cannot tell you when this will be published in racechrono.

Until then, you can use a Laptop or a Smartphone to play around with it. Take a Bluetooth Terminal application and send the above values to your bike.
After initialization, you can transfer 21 08 to your bike and it should respond with 51 values of data at once.

Good luck :slight_smile:

Just found this thread!

I'm doing this for Marelli Magnetti 15M ECU as used on Ducati and Guzzi in the late 90's.

Just looking at different displays. Small OLED or larger TFT or maybe old school matrix LCD.

The ECU has limited data available on the K/L interface, so I have GPS for speed and am looking at directly measuring injector pulses to get fuel consumption.

Will post a few pics of my birds nest...

Thanks for the response again TriB!

I'm waiting on the connectors to arrive from China. It will probably be a month or two more before I make my cable since the first connectors were incorrect. Since I have a late start to my season this year (Aug) I'm not in a huge rush to start. As soon as I get the connector though I'll give it a test!

Thanks again.

Hey guys, I'm working on acquiring RPM, TPS and ECT from my Yamaha 2019 bike (MT09/Tracer):
on the bike there is a DLC connector where I'm get connected on the CAN bus with MCP2515 module... I can read lot of CAN messages but since it support also the OBDII protocol I'm asking for the OBD PIDs and now I can succesfully get RPM and ECT (the value match the dashboard!) but I'm not sure about the TPS:
my bike has the ride by wire and I'd like to read the real TPS not the throttle/handle position because if I open full throttle the ride by wire may not open fully the "real throttle"... hope make sense for you.
In short: I'm asking the ODB PID 0x11 for Throttle position as described also in Wikipedia but I'm getting 14% value with throttle fully closed and aroound 28% at fully open (engine off). If I start the engine I'm getting 14% at idle and if I lightly open the throttle it get incresed but can't test at full gas...
The formula I use is simply : float tps = (100.0 / 255.0) * rxBuf[3];

Can you help me understand? I was expected 0% at least at fully closed

Hi Bullone,

that indeed is a bit strange. The TPS mostly means the angle from the throttle valve, not the gas!
So it is right, that it is opened a bit on idle. But it must exceed 28% on full throttle.
Or the ride by wire does not change the valve, when the bike does not run?!?

Nice to see, that you have RPM and stuff already working :slight_smile:

Yes it is strange but maybe the TPS is limited by the ride by wire maps on the ECU while not in gear and a very low RPM.... I have to test it on the road logging the value.

I'll let you know

Hi,
I just got started with this library.
I got a vfr 1200 and want to create a new cockpit.

I’ve order the additional component. And started with the emulator on a pi 3. But I can’t get it to work with the latest version of python.

It doesn’t handle request.clear()
Can you help out with a new version?

Tnx,
Steef

(Sorry, this post should have come in another thread on this forum)