iwanders / OBD9141

A class to read an ISO 9141-2 port found in OBD-II ports.
MIT License
232 stars 72 forks source link

How to tweak timing? #2

Closed fightforlife closed 4 years ago

fightforlife commented 8 years ago

Hey there, great code you have written here! I am trying to use your library in combination with an Arduino Mega and a MC33290 to log the RPM, TPS and AFR(analog) values of my motorcycle while driving (Triumph Daytona 675). With these information it is possible for me to correct the air values in the ECU and tune the bike for better performance!

For this usage it is imortant, that i can poll the TPS und RPM as fast as possible and both at (nearly) the same time. I already got everything working, but I hope there is some way to get it a little faster.

At the moment I need 120ms to get the RPM and the TPS values (around 60ms each). These are my timing settings from the header file:

# define OBD9141_KLINE_BAUD 10400
# define OBD9141_WAIT_FOR_ECHO 3
# define OBD9141_BUFFER_SIZE 16
# define OBD9141_INTERSYMBOL_WAIT 3
# define OBD9141_AFTER_REQUEST_DELAY 20
# define OBD9141_REQUEST_ANSWER_MS_PER_BYTE 3
# define OBD9141_WAIT_FOR_REQUEST_ANSWER_TIMEOUT 0
# define OBD9141_INIT_IDLE_BUS_BEFORE 1000
# define OBD9141_INIT_POST_INIT_DELAY 50

For testing the setup I use your reader example(slightly altered). Is there a possibility to poll these two values even faster? I need RPM & TPS as close together and often as possible. Thank you very much in advance!

iwanders commented 8 years ago

Hi,

Thanks, great to hear that someone else is also using my library. Were there any changes required to get it to work on the Arduino Mega?

I have made several changes to the way the timing is handled when dealing with the echo, these changes are in 50652162f17eeff8a8d47fb242a7c56575481107 and should improve the performance, it removes a delay(OBD9141_AFTER_REQUEST_DELAY) in the code. So depending on your ECU it might not change the results, but it might also decrease the time needed to get the PID by 20ms. Please give the new version a shot and tell me if it still works with the default settings for you.

In regard to your question how to tune the timing parameters, with the new changes incorporated I have added documentation on the timing in bc3909e61b7030c26a2a249ad67e56f1ac8416fb, I hope this explains a lot, but unfortunately the only timing parameter which we can really influence is the INTERSYMBOL_WAIT value, with the new echo handling the delay after the request is not required anymore. It is 5 ms according to the spec, with the ECU I have available for testing I can reduce this delay to 2 ms without problems, which puts me at about 50 ms per request. The main part of this is waiting on the ECU for ~35 ms unfortunately.

Please let me know if this clears things up.

fightforlife commented 8 years ago

Wow! Thank you very much for this detailed answer!

I use your library without modification on an Arduino Mega (from China). I set it to use the Serial3 Port with the corresponding pins. Flawless!

I am really new to using an Arduino, but your changes sound very promising. Sadly I cant test them right away, because I am not at home for some time. As soon as I get a chance (might be 1-2 months :( ) I will test the new code and try what is possible with the ECU on my motorcycle. Since the Bosh LSU wideband lambda has a response time of a little less than 100ms it would be quite nice to get the RPM and TPS in that timeframe. But it seems very possible.

Thanks again!

nautamaran commented 5 years ago

I've just downloaded this (Great!) class for use with a similar monitoring project, and intend to generalize some of the methods to improve support for connecting with arbitrary ECUs sharing a K-Line. Mainly parameterizing the target address to support physical addressing, and more complete parsing of the Format byte to adjust to possible header formats and message data lengths. In order to accommodate the possible timing ranges of my vehicle's ECUs (engine, trans, climate, abs, srs...) I will likely be adding auto-sensing and dynamic line timing adjustment to the class.

ISO 9141-2 specifies defaults for inter-byte and -message wait time ranges (the P1..P4 values) but ISO 14230-2 and -3 (and perhaps 9141-3?) provide ServiceID 0x83 (accessTimingParameters) for detecting/adjusting the timing values at run time.

SId . PId : Description 0x83 . 0 : requests the ECU's timing limits for P2min, P2max, ,P3min, P3max, and P4min 0x83 . 1 : sets timing to default values; 0x83 . 2 : read current timing values from the ECU 0x83 . 4 : sets timing to supplied values

The P_min values can often be set to zero for a fast ECU, but some require significant idle time.

In particular, setting P2min=0 minimizes the ECU's response delay, and setting P3min=0 minimizes idle time between client requests.

@iwanders : Ivor, I am BRAND NEW to GitHub, so please be gentle as I learn project etiquette around here, and know that I'd really like to contribute to the robustness and performance of this class. -dave

iwanders commented 5 years ago

Hi @nautamaran , welcome :)

As you've probably read in this thread and seen in the diagram this library only requires INTERSYMBOL_WAIT to be set, all other waits are handled by the readBytes function which returns as fast as possible.

I don't have any objections to changing the INTERSYMBOL_WAIT value from a define to an attribute of the class and providing a setter to change the value at runtime to make it possible to match it's value with the ECU's requirements at runtime.