mickeyl / LTSupportAutomotive

An iOS / watchOS / macOS support library for OBD2, VIN-Decoding, and more.
MIT License
212 stars 59 forks source link

Is it possible to get PID commands return data faster? #38

Closed opp100 closed 2 years ago

opp100 commented 2 years ago

Hey there,

Is there any way I can get the PID command return data faster?

Im using the code exactly same as Demo project. It is very slow for each PID command finish. it maybe takes more than 200+ms to read one data. I guess we can do something for transmitMultipleCommands function to improve the speed of loading.

-(void)updateSensorData
{
    LTOBD2PID_ENGINE_RPM_0C* rpm = [LTOBD2PID_ENGINE_RPM_0C pidForMode1];
    LTOBD2PID_VEHICLE_SPEED_0D* speed = [LTOBD2PID_VEHICLE_SPEED_0D pidForMode1];
    LTOBD2PID_COOLANT_TEMP_05* temp = [LTOBD2PID_COOLANT_TEMP_05 pidForMode1];

    [_obd2Adapter transmitMultipleCommands:@[ rpm, speed, temp ] completionHandler:^(NSArray<LTOBD2Command *> * _Nonnull commands) {

        dispatch_async( dispatch_get_main_queue(), ^{

            self->_rpmLabel.text = rpm.formattedResponse;
            self->_speedLabel.text = speed.formattedResponse;
            self->_tempLabel.text = temp.formattedResponse;

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self updateSensorData];
            });

        } );

    }];
}

NSlog:

-[LTOBD2AdapterInternalCommand didCompleteResponse:protocol:protocolType:] (LTOBD2Adapter.m:58) <LTOBD2PID_COOLANT_TEMP_05:0x28382ca20 = '0105'> complete [226 ms] => '83F1114105804B'
mickeyl commented 2 years ago

In general: No. With OBD2-commands, the bottleneck is the OBD2 adapter waiting for more responses.

That said, there are ways to manipulate these timings. You can try adjusting the init sequence with commands like:

Be warned though, don't set n too low, otherwise the adapter might stop waiting too early and respond with NO DATA.

If this still does not lead to enough speed, there are even more ways, but for these you will have to hack LTAutomotiveSupport:

Ravish1 commented 2 years ago

Hey @mickeyl thanks for the explanation regarding waiting time.Can you please tell me where to add 1 as suffix ,i am preety beginner to ios development .A single code line demo will be really appriciated .

mickeyl commented 2 years ago

Try applying the following diff to LTOBD2PID.m in +(instancetype)pidForMode1 (line 33).

-    NSString* string = [@"01" stringByAppendingString:suffix];
+    NSString* string = [NSString stringWithFormat:@"01%@1", suffix];

This way, an '1' will be appended to the PID, hence the adapter will stop after receiving one data message. Make sure you don't use this with broadcast addressing, otherwise you'll miss responses you actually want.

Note also that due to a bug in many ELM327ish implementations, this will not work with ISOTP multi-line answers (e.g. the answer to 0902) – the adapter stops listening after the first frame.

Ravish1 commented 2 years ago

Hey Thank you so much for replying."This will not work with ISOTP multi-line answers (e.g. the answer to 0902)".If we add suffix so it means it will only listen for "pidForMode1".Like multi line asnwer we cant recieve VIN NUMber ? Also Need little bit explatnation for "Make sure you don't use this with broadcast addressing, otherwise you'll miss responses you actually want".Thanks .

mickeyl commented 2 years ago

The change I've presented only adds the '1' for all PIDs in "current frame" (01xy), so you should be clear for all PIDs from 0100 to 01FF. If you were to do the same for PIDs in the range of "vehicle information" (09xy), then it won't work because most of these PIDs return ISOTP multi line answers like, e.g., VIN (0902).

With regards to broadcast addressing… OBD2 supports broadcast addressing e.g. in CAN11-mode it's when you send anything to 0x7DF. In that case, all of your OBD2-capable ECUs will answer. However – if you're applying the patch from above – you will only get the first ECU answering, since the adapter stops listening after the first answer. That's why you have to be a bit careful with broadcast addressing.

Of course, it would be best, if the library would support this, and in particular, if it could tune itself to work with many kinds of adapters, not just dumb ELM327 clones. All these ideas are way too complex to solve without the proper base infrastructure though.

(FWIW, I have realized all that in a Swift-based successor library Swift-UDS [which was open source for a short time], but I'm afraid this library is going to be have a proprietary license and will remain closed source.)

Ravish1 commented 2 years ago

Thank you so much for better clearification and awesome libraray.Worked really well .

Ravish1 commented 2 years ago

@mickeyl The libraray is working fine getting all the required data but sometime when adater state changed ,I am getting crash with odd logs .Whenever you have have time can you please check.Here the log which i am getting during crash - Unhandeld adapter state OBD2AdapterStateReady

Ravish1 commented 2 years ago

Hey @mickeyl any update on above crash things .It crashed multiple time with same error .

rs38 commented 2 years ago

for some reasons I cannot find any documented behaviour of ELM327 to alter the wait behavior with a suffix?! Pretty sure the suffix will be sent as raw data on the CAN bus...

mickeyl commented 2 years ago

@rs38 Straight from the horses mouth on page 31:

There is a way to speed up the retrieval of information, if you know how many responses will be sent. By telling the ELM327 how many lines of data to receive, it knows when it is finished, so does not have to go through the final timeout, waiting for data that is not coming. Simply add a single hex digit after the OBD request bytes - the value of the digit providing the maximum number of response to obtain, and the ELM327 does the rest.

rs38 commented 2 years ago

@mickeyl thanks, I should read more carefully! will test it and wonder if I can speed up also UDS $22 readbyID commands! (Your advice regarding dynamically defined data identifier $2C seems unsupported for many BEVs?!)

mickeyl commented 2 years ago

@rs38 Yes, UDS $2C might not be supported. Note that it's definitely only supported for direct adressing, not for broadcast addressing.

rs38 commented 2 years ago

@mickeyl can you give 1-2 examples of cars that support $2c? My last try always returns like negative responses 7F ?? 11 or similar.

BTW: The suffix "1" for single DID $22 UDS queries works but not tested for performance improvements 👍

mickeyl commented 2 years ago

@rs38 Should be quite a lot of cars, actually. 0x2C is supported by many BOSCH ECUs, e.g. the EDC45CP45 I have here:

>2c01f300f1900111
7E8 6C 01 F3 00

>22f300
7E8 7F 22 78
7E8 62 F3 00 57 44 44 32 31 32 30 39 34 31 42 32 30 34 32 35 35
rs38 commented 2 years ago

@mickeyl good point! I think I only tested the BMS (11bit CAN id 0x7E5, ECU 0x8C) by physically addressing, so the success could be different from ECU to ECU in one car?!

may I add another question now that I have contact to an UDS guru? :)

Is there a way to translate from ECU ID like VAG cars use image to physical 11 bit and/or 29bit CAN headers ID? in many VW BEVs you can reach certain ECUs by either 11 or 29 bit addressing at least from diag OBD port and probably the gateway routing either way.