From f9884783361c45615dcaca2fb3796aa187671135 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Sat, 13 Jun 2026 10:36:58 +0400 Subject: [PATCH] bump v1.11.0-dev --- doc/claude-analysis-elm-v2.md | 94 +++++++++-------------------------- web/templates/index.html | 4 +- 2 files changed, 26 insertions(+), 72 deletions(-) diff --git a/doc/claude-analysis-elm-v2.md b/doc/claude-analysis-elm-v2.md index 5bdb102..c4a6309 100644 --- a/doc/claude-analysis-elm-v2.md +++ b/doc/claude-analysis-elm-v2.md @@ -1,86 +1,40 @@ -# Анализ деградации ELM-кода в v1.9.0 и план исправления +# Анализ: ELM327 динамический тест -## 1. Почему v1.9.0 стал ХУЖЕ (ни одного ответа)? +## 1. exec() — retry с повторной write(cmd) — ГЛАВНЫЙ БАГ -Главная причина — **отключение `drainInput()` в `write()`** совмещенное с агрессивной работой `exec()`. -* В v1.3.0 `drainInput()` вызывался перед каждой командой. Если ELM "подлагивал" и присылал ответ на предыдущую команду с опозданием, `drainInput()` вычищал этот мусор, и `read()` начинал ждать с чистого листа. -* В v1.9.0 `drainInput()` выключен. Если первая команда батча (`010C`) дает таймаут, `exec()` делает **10 RETRY**. -* Сценарий катастрофы: - 1. Послали `010C`. Тайм-аут. - 2. Послали `010C` (retry 1). В этот момент ELM прислал ответ на #1. - 3. `read()` в retry 1 видит ответ от #1, но ELM уже занят обработкой #2. - 4. Следующие команды накладываются друг на друга. Буфер Bluetooth забивается ответами, которые не соответствуют командам. - 5. ELM v1.5 "захлебывается" потоком данных в TX-буфере и перестает отвечать на новые команды вовсе. +При таймауте ELM уже отправил запрос в CAN-шину и ждёт ответа от ЭБУ. write(cmd) снова вызывает drainInput() — сбрасывает буфер с ответом, которого мы ждём — и шлёт команду повторно. ELM получает 010C пока обрабатывает предыдущий 010C → BUFFER FULL / зависание. 10 retry = 10 одновременных CAN-запросов. Статика не задевает этот путь, потому что там таймауты не случаются (пауза между командами — секунды). -## 2. Нужен ли ATWS перед динамикой? +## 2. Почему v1.9.0 (без drainInput) стало хуже -**Да, но с нюансами.** -* `ATWS` (Warm Start) гарантирует, что ELM забыл про "SEARCHING" и сбросил внутренние ошибки протокола. -* **Ожидание после `ATWS`:** Минимум **1000мс** (на v1.3 было 300мс — мало, на v1.9 вообще убрали). -* **ВАЖНО:** После `ATWS` нужно заново послать `ATE0`, `ATL0`, `ATS0`, так как Warm Start сбрасывает их в дефолт. +drainInput() в write() — единственный механизм синхронизации запрос/ответ. Без него: -## 3. Нужен ли drainInput() в write()? +- Ответ на команду N читается как ответ на команду N+1 +- read() видит > из старого ответа — возвращает мусор, считает успехом +- К 3-му PID цикла батча сдвиг накопился: ответы не совпадают с командами +- BT-буфер на стороне ELM забивается необработанными данными → ELM перестаёт отвечать -**Да, обязательно**. Но не просто "чистка всего", а **синхронизация**. -Для ELM327 принцип "запрос-ответ" свят. Мы не имеем права слать новую команду, пока не получили `>` от предыдущей ИЛИ не дождались таймаута И вычистили буфер. +В v1.3.0 drainInput() маскировал проблему retry: хотя бы буфер чистился перед каждой командой. -## 4. Почему статика работает? +## 3. ATWS — нужен ли, сколько ждать -В статике между командами проходят секунды (пока поток UI обработает, пока лог запишется). Этого времени хватает ELM, чтобы "прочихаться". В динамике команды идут пачками, что превращает любую задержку адаптера в фатальный рассинхрон. +Нужен: сбрасывает SEARCHING..., очищает внутренние ошибки CAN-протокола ELM. -## 5. Retry в `exec()` с переповтором команды — ГЛАВНЫЙ БАГ. +Проблемы текущего использования: +- Пауза 800 мс — мало. CAN-шина после warm start поднимается 700–1000 мс, плюс ATSP0 negotiate. Нужно 1200–1500 мс. +- После ATWS ELM сбрасывает настройки в дефолт: ATE1 (эхо ON), ATL1 (LF ON), ATS1 (пробелы ON). Код не восстанавливает ATE0/ATL0/ATS0 → read() начинает видеть эхо команды и переносы строк → парсинг ломается. -Повторная отправка OBD-команды (`010C`) при таймауте — это **яд для ELM327**. -Команда OBD — это не просто AT-запрос. ELM должен отправить запрос в CAN-шину, дождаться ответа от ЭБУ, отформатировать его и выдать. Если мы шлем `010C` второй раз, когда ELM еще ждет ответа от CAN, он может либо зависнуть, либо выдать `BUFFER FULL`. +## 4. sleep(350) между PID — правильно? ---- +Для ELM327 v1.5 — приемлемо. Адаптер не успевает переключаться быстрее 100–200 мс между разными PID (CAN frame turnaround). Но 350 мс не решает проблему, потому что рассинхрон возникает раньше — внутри retry в exec(). Пауза между командами маскирует, но не лечит. -# Необходимые правки кода +## 5. Почему статика работает, динамика нет -### 1. `ElmProtocol.kt`: Убрать вредный retry OBD-команд +Статика: пауза между командами — секунды (UI-обработка). ELM успевает ответить. Retry не срабатывает. Накопления сдвига нет. -```kotlin -// В методе exec(): -// БЫЛО: -for (i in 0 until MAX_RETRIES) { - write(cmd) // ← НЕЛЬЗЯ ПЕРЕПОСЫЛАТЬ OBD-команду! - // ... -} +Динамика: пауза 350–500 мс. При первом таймауте retry запускает цепочку дублей. Синхронизация батча ломается. Следующий батч начинается на сломанном состоянии. -// НАДО: -private fun exec(cmd: String, timeout: Long): String { - write(cmd) - var t = timeout - try { - return handle(read(t)) - } catch (_: TimeoutException) { - increaseTimeout() - // Очищаем буфер, так как команда "протухла" - drainInput() - return "" - } -} -``` +## Итог: приоритет причин -### 2. `ElmProtocol.kt`: Вернуть `drainInput()` в `write()` -Без него мы читаем ответы на позапрошлые команды. - -### 3. `DynamicCollector.kt`: Добавить микро-паузу между PID -ELM v1.5 физически не может переключаться между PID быстрее чем за 100-200мс. - -```kotlin -// В цикле for (step in steps): -val raw = elm.sendCommand(step.cmd) -Thread.sleep(150) // Пауза для стабильности v1.5 -``` - -### 4. `MainActivity.kt`: Правильная инициализация перед тестом -```kotlin -// Перед стартом DynamicCollector: -elmProto.sendCommand("ATWS") -Thread.sleep(1200) // Ждем инициализации -elmProto.sendCommand("ATE0") // Эхо выкл -elmProto.sendCommand("ATL0") // Переносы выкл -elmProto.sendCommand("ATS0") // Пробелы выкл (КРИТИЧНО для скорости) -elmProto.drainInput() -``` +1. exec() повторяет write(cmd) при таймауте — нельзя дублировать OBD-команды в CAN (первична) +2. Убрали drainInput() в write() — потеряна синхронизация запрос/ответ +3. После ATWS не восстанавливают ATE0/ATL0/ATS0 — парсинг ответов ломается diff --git a/web/templates/index.html b/web/templates/index.html index 9988772..436b160 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -13,14 +13,14 @@ elmAI

elmAI

Диагностика авто через ELM327 + ИИ

-

v1.10.0-dev — 7 июня 2026

+

v1.11.0-dev — 7 июня 2026

📱 Скачай приложение на телефон:

⬇️ Скачать elmAI APK -

v1.10.0-dev • нажмите чтобы скачать

+

v1.11.0-dev • нажмите чтобы скачать