From 5eeda440be8957d0fa14868eec0f9128786c9529 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Wed, 10 Jun 2026 22:44:43 +0400 Subject: [PATCH] bump v1.9.0-dev --- doc/claude-analysis-elm.md | 43 ++++++++++++++++++++++++++++++++++++++ web/templates/index.html | 4 ++-- 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 doc/claude-analysis-elm.md diff --git a/doc/claude-analysis-elm.md b/doc/claude-analysis-elm.md new file mode 100644 index 0000000..768208a --- /dev/null +++ b/doc/claude-analysis-elm.md @@ -0,0 +1,43 @@ +# Анализ причин отказа ELM327 v1.5 при динамическом опросе + +Анализ кода `ElmProtocol.kt`, `DynamicCollector.kt` и `ElmChecker.kt` выявил ряд критических проблем, которые в совокупности приводят к "зависанию" адаптера ELM327 (особенно дешевых клонов v1.5) при переходе к быстрому циклу опроса. + +## Ответы на вопросы + +### 1. Почему ELM327 v1.5 замолкает после первых 2 ответов? +Основная причина — **десинхронизация и переполнение буфера**. +* **ATWS прямо перед циклом:** Команда `ATWS` (Warm Start) сбрасывает микроконтроллер. Ему требуется время на инициализацию (обычно 500-1000 мс). Код в `MainActivity` ждет всего 300 мс. Первые команды `010C` прилетают, когда ELM еще "просыпается" или находится в неопределенном состоянии. +* **Эффект домино в `exec()`:** Если первый PID в цикле (`010C`) не успел ответить вовремя, `exec` возвращает пустую строку, но ELM продолжает обработку. Следующий вызов `sendCommand` через `write()` делает `drainInput()`, удаляя запоздавший ответ, и посылает новую команду. Для клона v1.5 типична ситуация, когда он "захлебывается", если получает новую команду, не закончив передачу предыдущего ответа или символа `>`. + +### 2. Может ли `drainInput()` в `write()` съедать ответ? +**Да, и это главная проблема надежности.** +Если ELM327 ответил на 50 мс позже таймаута, данные уже лежат в буфере Bluetooth-сокета. Вызов `write()` для следующей команды в цикле безусловно их очищает. В итоге `read()` следующей команды видит пустоту, провоцируя новые таймауты и ретраи. Происходит рассинхрон: приложение ждет ответ на команду B, а ELM (если не завис) шлет ответ на команду A. + +### 3. Критична ли последовательность: static -> speed-test -> ATWS -> dynamic? +Последовательность перегружена сбросами. +* `ATWS` сбрасывает настройки `ATAT1`, `ATSP`, `ATL0` и т.д., которые были установлены в `init()`. +* После `ATWS` протокол может вернуться к `AUTO` (`ATSP0`), что заставляет ELM тратить время на "SEARCHING..." при первом же запросе `010C`. Это гарантированный таймаут в динамическом тесте. + +### 4. Нужно ли переподключать ELM вместо ATWS? +Переподключать Bluetooth-сокет не обязательно, но **вместо `ATWS` лучше вызвать серию настроечных команд**, гарантирующих состояние: +1. `ATE0` (эхо выкл) +2. `ATL0` (переносы строк выкл) +3. `ATS0` (пробелы выкл) — крайне важно для скорости и предотвращения переполнения буфера. +4. `ATSP X` (принудительная установка протокола, найденного в `checkDevice`), чтобы исключить стадию поиска. + +### 5. Как правильно реализовать динамический опрос для v1.5? +Для минимизации ошибок на медленных адаптерах: +1. **Убрать `Thread.sleep(350)` внутри цикла `for (step in steps)`.** Пауза должна быть только между *пакетами* (батчами) PID, если нужно ограничить частоту. Внутри батча команды должны идти максимально плотно: послал -> дождался `>` -> сразу следующий. +2. **Увеличить таймаут для v1.5.** 500 мс — это предел для v1.5. Первичный запрос (особенно после сброса) может занимать до 1500 мс. +3. **Оптимизировать `read()`:** v1.5 очень чувствителен к таймингам. Текущий `Thread.sleep(1)` в `read()` — это хорошо, но логика `drainInput` должна быть перемещена: чистить буфер нужно только один раз *перед стартом всего динамического теста*, а не перед каждой командой. + +## Рекомендации по исправлению + +1. **В `ElmProtocol.kt`:** + * Сделать `drainInput()` опциональным параметром в `write()` или убрать его из `sendCommand` по умолчанию. + * В `handle()` при получении `NODATA` или `ERROR` не делать `ATWS` мгновенно, так как это убивает сессию опроса. +2. **В `DynamicCollector.kt`:** + * Удалить `Thread.sleep(350)` в цикле `for`. Вместо этого полагаться на таймауты `ElmProtocol`. +3. **В `MainActivity.kt`:** + * Убрать `ATWS` перед стартом. Если нужен сброс — использовать `ATZ` и ждать 2 секунды, после чего заново прогнать весь `init()`. + * Перед запуском `DynamicCollector` зафиксировать протокол: `elmProto.sendCommand("ATSP" + currentProtocol)`. diff --git a/web/templates/index.html b/web/templates/index.html index 6f1a01f..302ef9a 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -13,14 +13,14 @@ elmAI

elmAI

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

-

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

+

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

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

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

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

+

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