fesch / CanZE

Take a closer look at your ZE car
http://canze.fisch.lu
Other
120 stars 70 forks source link

Incomplete reply when initializing iCar Pro #775

Open mgottschlag opened 1 year ago

mgottschlag commented 1 year ago

Symptoms

When reading my Zoe R110 with an iCar Pro OBD2 adapter, I always received an error about an invalid version. More specifically, CanZE thought that the version string would just be "atws". I managed to get the adapter to work exactly once after executing some other ELM327 tester app, as was reported on some german Zoe forum. I never managed to repeat that, though. Other people on those forums also report problems with the iCar Pro.

Analysis

Other applications were able to use the adapter, and manual interaction with the adapter showed that it replied to atws with "atws\r\r\rELM327 v2.3" (or similar, I do not recall the exact details). Increasing the timeout for "wait-until-no-further-data"-commands in ELM327.java fixed the issue, so apparently the original 50 milliseconds are just too short for the iCar Pro. Manual experiments seem to show that atws requires less than 250ms, but I did not perform any proper measurements.

Hackfix

The following diff is what I currently use. This fix is not really good. Instead of waiting once to check again whether there is no data, the app should periodically poll the serial port for data, and only when N retries did not yield any data, the app should assume the command to be finished. The total timeout N * 50ms (for example) should be long enough for adapters such as the iCar Pro.

Also, note how I abused the unused waitMillis parameter. That parameter should probably be replaced with a flag that indicates that the reply to the command could take a while.

diff --git a/app/src/main/java/lu/fisch/canze/devices/ELM327.java b/app/src/main/java/lu/fisch/canze/devices/ELM327.java
index 3f3a66c9..aa4b5d2f 100644
--- a/app/src/main/java/lu/fisch/canze/devices/ELM327.java
+++ b/app/src/main/java/lu/fisch/canze/devices/ELM327.java
@@ -120,9 +120,9 @@ public class ELM327 extends Device {

         if (toughness == TOUGHNESS_HARD || toughness == TOUGHNESS_MEDIUM) {
             // the default 500mS should be enough to answer, however, the answer contains various <cr>'s, so we need to set untilEmpty to true
-            response = sendAndWaitForAnswer("atws", 0, true, -1, true);
+            response = sendAndWaitForAnswer("atws", 500, true, -1, true);
         } else { // TOUGHNESS_WEAK
-            response = sendAndWaitForAnswer("atd", 0, true, -1, true);
+            response = sendAndWaitForAnswer("atd", 500, true, -1, true);
             MainActivity.debug("ELM327: version = " + response);
         }
         MainActivity.debug("ELM327: version: [" + response + "]");
@@ -425,7 +425,12 @@ public class ELM327 extends Device {
                                 if (stop) {
                                     // wait a fraction
                                     try {
-                                        Thread.sleep(50);
+                                        if (waitMillis > 50) {
+                                            Thread.sleep(400);
+                                        } else {
+                                            Thread.sleep(50);
+                                        }
+                                        end = Calendar.getInstance().getTimeInMillis() + generalTimeout;
                                     } catch (InterruptedException e) {
                                         // do nothing
                                     }