Go Down

Topic: Bike interface OBD (Read 125690 times) previous topic - next topic

IgorShobik

Hi TriB, thanks for the answer. I know that you are a doctor in these matters.
I tried  and your code too - not secess
I dont know ECU manufacturer in my bike. I know about Denso and Mitsubishi ECU manufacturer for Kawasaki.
Theoretically, the protocols may differ, but I do not understand why kawasaki needs this.

IgorShobik

For information.
There is a suspicion, that the motorcycle protocols for the European and American markets are different. Everything is ok with European motorcycles - there is a problem with American motorcycles - now we will check the version with K and L line for connect.

TriB

I have z1000 my2012 from USA, in this ECU there is no immobilizer and there is no sensor lambda.

I cannot connect to the ECU via the k-line bus. I use k-line, GND and + 12V from the diagnostic socket. No connection even when using ELM327 and Torque app, but with another z1000 my2017 motorcycle the connection is ok.

Before that I used arduino to connect and the result was negative.

Can you tell me what idea to make a connection?
Almost 110% of all ELM327 adapters are chinese clones and do not support proper programming (like setting the custom header, keepalive-message or initialization), nor do they support the K-Line properly.

My personal rule of thumb is: Below 50 bucks (€ or $) it´s a clone and will not work with motorbikes.
Purchasing a L9637D, some resitors and stuff will cost you 5 bucks and you will find out!

PS: My 2012 Z750r has the immobilizer but no lambda as well.

ivashkoartem

#213
Nov 25, 2019, 11:07 pm Last Edit: Nov 25, 2019, 11:12 pm by ivashkoartem
Sorry, but I have only elm327 from aliexpress. This elm327 connect to bike my friend without trouble (z1000 my2010, but ecu z1000sx 2015+), my bike doesn't connect.

I am 100% sure in the elm327 device that it works with kawasaki using the iso14230 protocol.

I have arduino leonardo and L9637d, I could not connect to the ECU my bike.

If  use l-line additionally, there is also no result.

I don't understand which device to check the operation of k-line, except elm327

Earendil86

Hello! I'm back. I'm about a year delayed from where I wanted to be on this project. But here goes.

I finally managed to find the time to make my Suzuki SDS to OBD connector and install in permanently on my bike for easy access at the track. I downloaded a bluetooth terminal and sent the commands and at first I didn't get responses. Then, following another forum from Racechrono, I added a line and it worked. My first questions revolves around that extra line because after I entered it, the second time I did the codes I tried without and it worked. Do you only have to set this line once and the ECU remembers it? Or once every time a battery has been disconnected? Here is what I entered the first time:

ATZ (Determines ELM327 Version)
ATWM8012F1013E (set a special keep alive message)
ATSH8112F1 (initialize with 0x81 header)
ATFI (initialize bus. IE: start communication)
ATSH8012F1 (reset header to 0x80)
2108 (Read Data by Local ID)

did not get a response. Added ATSP5 and it worked:

ATZ (Determines ELM327 Version)
ATSP5 (manually setting the protocol to 5)
ATWM8012F1013E (set a special keep alive message)
ATSH8112F1 (initialize with 0x81 header)
ATFI (initialize bus. IE: start communication)
ATSH8012F1 (reset header to 0x80)
2108 (Read Data by Local ID)

Why is this necessary? And again, why did I not need to enter this afterwards after ended communication, switching to a different bluetooth terminal and reentering the first set of commands?

Continuing...

Second question. I tested two conditions with the ignition on but bike off. Throttle off and throttle full open and received the following results:

>2108 (Throttle closed)

61 08 01 17 69 A2 00 00 00 FF FF FF 00 00 00 39
BA 36 38 BB 00 FF 00 FF 7C 35 FF 00 00 00 00 00
00 00 00 FF FF 40 40 40 40 FF FF 00 74 15 30 04
05 28 FF FF

>2108 (Throttle full open)

61 08 01 17 69 A2 00 00 00 FF FF FF 00 00 00 E0
BA 36 38 BB 00 FF 00 FF 7C 35 FF 00 00 00 00 00
00 00 00 FF FF 40 40 40 40 FF FF 00 74 15 30 04
05 28 FF FF

So the top right value is for throttle position. That being said. I have zero idea as to what the rest of the string represents. Does anyone have a link to a site that has already explained each part of the 2108 Suzuki response and linked to what it represents? I did some searching and I can't (quickly) find that so I figured that I would ask to see if anyone has this information. The values that I'm most interested in are:

Speed
RPM
Throttle Position (Have)
Coolant Temp
Gear

But it would be great to at least know which each of those values means.

After that, I need to work on determining how to enter these into Racechrono to pull those values while riding and will continue in the thread that TriB already pointed me to:

https://racechrono.com/forum/discussion/1724/newbie-question-regarding-bike-obd

TriB

Hi,

that´s quite simple:
Why is this necessary? And again, why did I not need to enter this afterwards after ended communication, switching to a different bluetooth terminal and reentering the first set of commands?
The ELM327 has to determine the (ISO-)protocol on startup. It mostly starts with the most common and if this does not work, the adapter automatically tests all avaliable protocols, one after another.
But due to the init process with 0x80 & 0x81 header, the ELM327 never gets a response. So the automatic-feature does not work on you bike.

Setting the protocol now to 5, will be stored until the EML327 is powered off or resetted.

So the top right value is for throttle position. That being said. I have zero idea as to what the rest of the string represents. Does anyone have a link to a site that has already explained each part of the 2108 Suzuki response and linked to what it represents? I did some searching and I can't (quickly) find that so I figured that I would ask to see if anyone has this information.
You can find the infos here in this thread, on the ECU Hacking board or in osi´s GitHub.
But from my findings, the calculations are not completely correct.

1 Header
2 Dongle
3 ECU
4 Messagesize
5 SID
6 PID
7 No of DTC
8 Freezed Frame 1
9 Freezed Frame 1
10
11 Freezed Frame 2
12 Freezed Frame 2
13
14
15
16
17 Speed
18 RPM A
19 RPM B
20 TPS
21 Intake Air pressure
22 Engine Temp
23 Intake Air Temperature
24 EAP - hPa
25 Batt
26 O2 sensor Bank 1
27 Gear
28 Intake Air Pressure 2
29 Idle Speed
30 Idle Speed Control Valve Position
31
32 High Cylinder 1 injection time (ms)
33 Low
34 High Cylinder 2 injection time (ms)
35 Low
36 High Cylinder 3 injection time (ms)
37 Low
38 High Cylinder 4 injection time (ms)
39 Low
40
41
42
43
44
45
46
47 Sub-Throtle Sensor
48
49
50
51 Cooling Fan Relais
52 Exhaust Control Valve
53 Clutch / Starter Relais
54 Neutral
55
56
57 Checksum

The values from 50 above, are booleans inside of a byte.
The neutral switch, for example is byte 54, the second bit.
Exhaust Control selector is also byte 54, but bit 8.

Earendil86

Hello,

I compared your output to mine (and others that I've found through your links) and also compared the output to testing that I did and I believe that the PID assignments are identical if you start looking at 61 as the first byte and removing some others that I don't seem to have (TriB's 13-16). The tests that I did helped me uncover RPM, Speed, Engine coolant temp, Gear and throttle position locations. Then, reviewing your sheet to my results it appears as if they used the same spacing so I've done my best to fill it out below for my bike.

What I'm hoping to do is to clarify the names for each PID as I'm not actually 100% confident that I know the acronym as well as the formula's that people use (with Units) for conversion. I've taken the formulas that I've found from TriB's posts, O5i's GitHub, and Aster's GitHub.

If anyone has the time who has gone through the formula's themselves, I'd appreciate comments when there are multiple formula's as to what your thoughts are.

If you're in a rush and want to help, the main PIDS (and therefore formulas) that I'm concerned with are:

Speed (13), RPM (14/15), Throttle Position (16), Engine Coolant Temp (18)

Ultimately, I'd like to answer all of my questions though for my understanding before proceeding to RaceChrono and starting to enter the custom PIDs.

TriB - what's your process for refining formulas? Trial and error? Or are you able to get these somehow from the bike?

PID # LIST
* means that I have confirmed this PID for my 2013 Suzuki GSXR-1000 through testing

1 - 0x61 - Header (What is this?)
2 - 0x08 - Dongle (What is this?)
3 - 0x01 - ECU
4 - 0x17 - Message Size (What is this?)
5 - 0x69 - SID (What is this?)
6 - 0xA2 - PID (What is this?)
7 - 0x00 - Number of DTC (Diagnostic Trouble Codes)
8 - 0x00 - Freezed Frame 1 Byte 1(Assuming this stores data in two bytes when a DTC is registered?)
9 - 0x00 - Freezed Frame 1 Byte 2
10 - 0xFF - Not Used (or unknown)
11 - 0xFF - Freezed Frame 2 Byte 1
12 - 0xFF - Freezed Frame 2 Byte 2
13* - SPEED

[Aster94] Formula: SPEED = BYTE * 2 (km/h?)
I believe that this is actually just direct conversion to km/h with no formula? TriB?

14* - RPM High Byte (Rotations Per Minute)
15* - RPM Low Byte (Rotations Per Minute)

Formula:
[Aster94] RPM = HIGH BYTE * 10 + LOW BYTE / 10 (Appears incorrect for me)
[O5i] RPM = Value*100/255 (Can't be since only 1 value) (Appears incorrect for me)
[TriB] RPM = (HIGH BYTE * 255 + LOW BYTE) / 255 * 100 (Appears CORRECT for my data)

16* - TPS (Throttle Position Sensor)

Formula: (None of these seem to line up for me as they all show roughly the same %)
[Aster94] TPS = 125 * (BYTE - 55) / (256 - 55) (Unit? %?)
[TriB] Throttle Position % = BYTE / 255 * 100
[TriB] Throttle Position Deg = BYTE / 2
[O5i] Throttle position (°) = Value*125/255


17 - IP / IAP / MP (Intake Air Pressure)

Formula: (All similar results)
[Aster94] IAP = BYTE * 4 * 0.136 (kPa)
[TriB] Manifold Pressure: A * 166.7 / 255 - 20  (kPa)
[O5i] Manifold pressure = (Value*5 - 153)*133/4/255 (kPa)

18 - ECT (Engine Coolant Temperature)

Formula: (Why O5i has two separate formulas?)
[Aster94] ECT = (BYTE - 48) / 1.6 (°C)
[O5i] Temp °C = ( [Hex value] - 48) / 1.6 (°C)

[TriB] Engine Coolant: A * 160 / 255 - 30 => °C
[O5i] Temperature (C) = Value*160/255 - 30
[O5i] Temperature (F) = Value*288/255 - 22

19 - IAT (Intake Air Temperature)

[Aster94] Formula: IAT = (BTYE- 48) / 1.6 (°C)
[O5i] Temp °C = ( [Hex value] - 48) / 1.6 (°C)
[O5i] Temperature (C) = Value*160/255 - 30
[O5i] Temperature (F) = Value*288/255 - 22

20 - EAP/AP (Exhaust Air Pressure???)

[Aster94] Formula: AP = BYTE * 4 * 0.136 (Units??)
[TriB] - hPa (no formula? Just conversion then?)


21 - Batt (Battery Voltage)
Formula:
[Aster94] voltage = BYTE * 100 / 126 (Volts)
[O5i] Voltage = Value*20/255 (I like this one's results)

22 - O2 / H02 (Heated Oxygen Sensor Bank 1)
23* - Gear / GPS (Gear Position Sensor)

Formula: 0x00 = Neutral, 0x01 = Gear 1, 0x02 = Gear 2, 0x03 = Gear 3 etc.

24 - 0xFF - Not Used (or unknown) - TriB - has IAP 2 here
25 - IST (Idle Speed Target)
26 - ISC (Idle Speed Control Valve Position)
27 - 0xFF - Not Used (or unknown)
28 - Fuel Hi 1 (High Cylinder 1 injection time (ms))
29 - Fuel Lo 1 (Low)
30 - Fuel Hi 2 (High Cylinder 2 injection time (ms))
31 - Fuel Lo 2 (Low)
32 - Fuel Hi 3 (High Cylinder 3 injection time (ms))
33 - Fuel Lo 3 (Low)
34 - Fuel Hi 4 (High Cylinder 4 injection time (ms))
35 - Fuel Lo 4 (Low)
36 - 0xFF - Not Used (or unknown)
37 - 0xFF - Not Used (or unknown)
38 - IGN 1 - Ignition 1
39 - IGN 2 - Ignition 2
40 - IGN 3 - Ignition 3
41 - IGN 4 - Ignition 4

Formula: (PIDs: 38-41)
IGN = 0.4 * BYTE - 12.5

42 - 0xFF - Not Used (or unknown)
43 - STP/STPS/STVA (Secondary Throttle Position Sensor/Actuator)

Formula:
[Aster94] STP/STPS/STVA = BYTE * 100 / 255 (Units?)
[TriB] STP = BYTE / 255*100 (%)
[O5i] Secondary throttle position (%) and EXCVA sensor = Value*100/255

44 - ????
45 - ????
46 - ????
47 - CPR (Cooling Fan Relay)
48 - PAIR/ECV (PAIR Valve / Exhaust Control Valve)

[Aster94] Formula = BYTE (units?)

49* - Clutch (Indicates if the clutch is engaged)

Formula: 0x15 = Clutch engaged, 0x05 = Clutch disengaged

50* - Neutral/Gear (Indicates if the bike is in Neutral or Gear)

Formula: 0x28 = Neutral, 0x2A = In gear

51 - 0xFF - Not Used (or unknown)
52 - 0xFF - Not Used (or unknown)

Other formulas

(IAP = AP -IP)???
AFR - Air Fuel Ratio (IAP/ which fuel?)

TriB can you explain this in more detail? Maybe with an example?
The values from 50 above, are booleans inside of a byte.
The neutral switch, for example is byte 54, the second bit.
Exhaust Control selector is also byte 54, but bit 8.

TriB

Hi,

nice that you worked out the comparsion between all the formulas!
What have I done:
Gone to the racetrack and drove faster than ~125km/h and rised the RPM higher then 14.000.
Both leaded to drops (starting from a lower value again). So I started investigating!

On another thread about Kawasaki, I got dozens of conversations with Scissor about the calculations. He got the idea of the base of 256 for all values.
Tested a lot and compared it with the reality.

Last but not least, I got a Healtech SDS Tool and sniffed the data between the adapter and the software.
This finally made me creating a software, which can read the Healtech LOG-files and give me the results due to my calculations.
It is still not 100% right (but I think Healtech smoothen the values, so that you cannot always be sure).

The ECU´s are from the same manufacturer, so a lot is quite equal. But for me it seems that the base for Kawasaki is 256 and for Suzuki 255. Seems like a small difference, but makes huge drops!


I think you drifted on your
Quote
1 - 0x61 - Header (What is this?)
The header is always 0x80 or 0x81 and explains if the message is with length-information (which is only the case on initial protocol).
Dongle - The Receiver. The ID from your Diagnostic Adapter. Helps to see if the message is from you or from the ECU
ECU - Same like above. The Sender
Message Size - The number of the following bytes
SID - Service Identifyer
PID - Parameter Identifyer Just read this and you will understand anything :)

Freezed Frames - Both numbers leads you to the diagnostic trouble code, like 0105 -> Intake Pressure Sensor Error

Some values are unused or only for different bikes. Like desired RPM, which you can control via SDS, but not on my K6. If you need RPM 4.700, you can set it with a diagnostic command.
Or as you found yourself "Intake/Manifold Air Pressure (IAP)" & "Atmospheric Air Pressure (IAP 2)"

Battery - (A * 20 / 255)
EAP/AP - Exhaust Control Valve (A / 255 * 100)

The byte-thing is easy, if you understand it once!
When you have 0x04, you get this in binary
0000 0100

from right to left you have 128, 64, 32, 16, 8, 4, 2, 1
Bit 16 is uncheckt, so clutch is not pulled.
Bit 32 is the starter relais, which is also not used.

Pulling the clutch and press the starter will give you:
0011 0100
which is 0x34

This also seems to differ between the bikes. The Neutral-Switch on my bike seems to be on a different position.

Hope this helps for a bit of understanding!

Earendil86

Thanks! That's great.

I'm going to switch to focusing on entering the custom pids now in racechrono. I won't be able to take the bike out for another 2 months for on road testing :(

I'll check back from time to time to see if you've gotten further in your SDS and your formulas TriB!


junkienl

#219
Mar 13, 2020, 05:48 pm Last Edit: Mar 13, 2020, 06:00 pm by junkienl
Hello,

I have been trying to get a response from the ECU of my Kawasaki Vulcan 900 for some time now. Until now without any success. This what I am currently trying:

Hardware

I am using a L9637D chip in a circuit similar to this one:
https://github.com/aster94/Keyword-Protocol-2000

Which seems to be in accordance with:
https://www.st.com/resource/en/datasheet/l9637.pdf

I added a voltage regulator circuit to power the nano and a (high resistance) voltage divider on the K-line to be able to use the logic analyzer.

This circuit plugs into the 4-pin plug under my seat. There I find power, ground, K-line and an unused pin. I am pretty sure I know which pin is the K-line and which is the unused pin, but just to be sure, I have tried them both.



Code

My code is mostly a stripped-down version of:
https://bitbucket.org/tomnz/kawaduino/src/default/

At the moment I try to keep my code as simple as possible, because my aim for now is just getting any response from the ECU. For the initialization I use a sequence similar to:
https://github.com/HerrRiebmann/KDS2Bluetooth

The KDS2Bluetooth shows it working for a Kawasaki Z750. On Amazon I can find gear indicators that plug directly into the ECU, which are indicated for both this bike and my bike. This makes me believe I should be able to connect to my Vulcan 900 using the same initialization sequence:
  • K-line 2000 ms high (I use 2000 instead of 300, just to be on the safe side.)
  • K-line 25 ms low
  • K-line 25 ms high
  • Begin serial communication @ 10400 baud.
  • Send 0x81, 0x11, 0xF1, 0x81, 0x04.

This seems to agree with:
http://read.pudn.com/downloads118/ebook/500929/14230-2.pdf

Code: [Select]
#define K_OUT 1 // K Output Line - TX (1) on Arduino
#define K_IN 0  // K Input  Line - RX (0) on Arduino
const uint32_t ISORequestByteDelay = 10;
const uint32_t ISORequestDelay = 40; // Time between requests.

void setup() {
  pinMode(K_OUT, OUTPUT);
  pinMode(K_IN, INPUT);
}  
  
void loop(){
  uint8_t buf[5];
  uint8_t bytesToSend;
  uint8_t bytesSent = 0;
  buf[0] = 0x81;
  buf[1] = 0x11;     // ECUaddr
  buf[2] = 0xF1;     // myAddr
  buf[3] = 0x81;
  buf[4] = 0x04;
  bytesToSend = 5;
  digitalWrite(K_OUT, HIGH);
  delay(2000);
  digitalWrite(K_OUT, LOW);
  delay(25);
  digitalWrite(K_OUT, HIGH);
  delay(25);
  Serial.begin(10400);
  for (uint8_t i = 0; i < bytesToSend; i++) {
    bytesSent += Serial.write(buf[i]);
    delay(ISORequestByteDelay);
  }
  delay(500); // enough to get response
  Serial.end();
  delay(5000);
}


Results

As can be seen in the attached images: The K-line is doing something, but there is no response from the ECU.



There is also a closeup of the first byte:



I am not sure how the signal on the K-line should look. I can see that the 1st and 4th byte on the K-line are similar.

Can someone confirm if this is how this signal should look or that maybe my chip is faulty?

I have already tried different ECU addresses: 0x10 to 0x17. (and changed checksum of course)

Am I overlooking something? What else could I try? Any help is appreciated.

junkienl

#220
Mar 13, 2020, 11:50 pm Last Edit: Mar 13, 2020, 11:54 pm by junkienl
Small update...

I decided to look at the K-line signal on the oscilloscope:



After replacing the 100nF capacitor with 10nF it looked like this:



That made the difference! I got the correct response from the ECU:



It only works when the motor is not running, so reading rpm is a bit boring for now.

TriB

#221
Mar 16, 2020, 10:19 am Last Edit: Mar 16, 2020, 10:29 am by TriB
Hi junkienl,

Nice that you found the issue.
Why does it only work with engine not running?

Due to the fact I cannot see your current code, but see what you wrote about the initialization:

Kawasaki & Suzuki got exactly 3 (more or less big) differences:
  • ECU Addres: 0x11 / 0x28 Kawasaki 0x12 Suzuki
  • Kawasaki requires a "Start Diagnostic Session"-Message
  • Kawa requires one message per value, Suzuki sends them all at once


What you did right is part 1. But you (might) missed the second:

// Start Communication is a single byte "0x81" packet.
81 11 F1 81 04
// Response should be 3 bytes: 0xC1 0xEA 0x8F
//243 & 143 (Explaines supported Header type: Source, Target, Length & Checksum)
// Success, so send the Start Diag frame
// 2 bytes: 0x10 0x80
80 11 F1 02 10 80 14

The documentations says you can stop the diagnostic session, but in my findings this does not work!
Just quit the communication, like you started it, but with 0x82
81 11 F1 82 05

The Kawasaki will definitely send you all the values with a running engine, then!

PS: Btw, this thread is about Suzuki. The Kawasaki thread is here :)

junkienl

Hi TriB,

Thank you for replying. I saw the other thread, but I did not notice the Suzuki/Kawasaki distinction. I just tossed a coin and ended up here... :)

My problem seems to be a power issue. I got some rpm readings, but only after the warm up time when the rpm drops to normal idle. Just after startup the voltage is about 14,5 V. This is the handshake that I witnessed:

TX: 81 11 F2 81 05 - start communication
RX: 80 F2 11 03 C1 EA 8F C0 - accepted
TX: 80 11 F2 02 10 80 15 - start diagnostic
RX: 80 F2 11 02 50 80 55 - accepted

Revving the engine slightly makes the connection fail again. This is what I have tried so far:

1st test: Power the L9637D directly from the diagnostic plug.

2nd test: Power the L9637D through a L7812 voltage regulator. (I don't have a better regulator available. This one has a voltage drop of 1,7 V.)

For both cases:
-Works when engine off.
-Works when engine idling or slightly revving.
-Does not work for revving >2500rpm

I am not sure how to fix this… I will look through the threads and see what others have done.

TriB

The most common issue is in deed, that voltage drops or peaks affect the Arduino.
On my first "design" it happened, that the connection stopped after about 10 Minutes. But it ran for hours, connected to my ECU-Emulator, which simulated the ECU via USB.

But I´m not an electronics pro. A friend of mine did the PCB design. So I cannot really tell you, how to create a reliable power supply  :-[

uronour

I've only skimmed these pages briefly but I was in the middle of doing the ground work for something like this on Kawasaki ninja zx10r 2004
I had previously strayed on an 07 plate that was unfortunately stollen last year...

I had very small success with the 07 but I used a cheap elm odbII adapter, it read commands mad the Bluetooth software actually picked it up briefly, anyway that said.

Would anybody have clear cut instructions of the simplest way to do this? I'm after building my own mini dash and diagnostics, possibly camera overlay data unsure yet, I did build the basic circuit as I said earlier using L9637D but I couldn't get it working, struggled with getting the pins right I couldn't get any read out at all

Go Up