41 lines
3.8 KiB
Markdown
41 lines
3.8 KiB
Markdown
# Анализ: ELM327 динамический тест
|
||
|
||
## 1. exec() — retry с повторной write(cmd) — ГЛАВНЫЙ БАГ
|
||
|
||
При таймауте ELM уже отправил запрос в CAN-шину и ждёт ответа от ЭБУ. write(cmd) снова вызывает drainInput() — сбрасывает буфер с ответом, которого мы ждём — и шлёт команду повторно. ELM получает 010C пока обрабатывает предыдущий 010C → BUFFER FULL / зависание. 10 retry = 10 одновременных CAN-запросов. Статика не задевает этот путь, потому что там таймауты не случаются (пауза между командами — секунды).
|
||
|
||
## 2. Почему v1.9.0 (без drainInput) стало хуже
|
||
|
||
drainInput() в write() — единственный механизм синхронизации запрос/ответ. Без него:
|
||
|
||
- Ответ на команду N читается как ответ на команду N+1
|
||
- read() видит > из старого ответа — возвращает мусор, считает успехом
|
||
- К 3-му PID цикла батча сдвиг накопился: ответы не совпадают с командами
|
||
- BT-буфер на стороне ELM забивается необработанными данными → ELM перестаёт отвечать
|
||
|
||
В v1.3.0 drainInput() маскировал проблему retry: хотя бы буфер чистился перед каждой командой.
|
||
|
||
## 3. ATWS — нужен ли, сколько ждать
|
||
|
||
Нужен: сбрасывает SEARCHING..., очищает внутренние ошибки CAN-протокола ELM.
|
||
|
||
Проблемы текущего использования:
|
||
- Пауза 800 мс — мало. CAN-шина после warm start поднимается 700–1000 мс, плюс ATSP0 negotiate. Нужно 1200–1500 мс.
|
||
- После ATWS ELM сбрасывает настройки в дефолт: ATE1 (эхо ON), ATL1 (LF ON), ATS1 (пробелы ON). Код не восстанавливает ATE0/ATL0/ATS0 → read() начинает видеть эхо команды и переносы строк → парсинг ломается.
|
||
|
||
## 4. sleep(350) между PID — правильно?
|
||
|
||
Для ELM327 v1.5 — приемлемо. Адаптер не успевает переключаться быстрее 100–200 мс между разными PID (CAN frame turnaround). Но 350 мс не решает проблему, потому что рассинхрон возникает раньше — внутри retry в exec(). Пауза между командами маскирует, но не лечит.
|
||
|
||
## 5. Почему статика работает, динамика нет
|
||
|
||
Статика: пауза между командами — секунды (UI-обработка). ELM успевает ответить. Retry не срабатывает. Накопления сдвига нет.
|
||
|
||
Динамика: пауза 350–500 мс. При первом таймауте retry запускает цепочку дублей. Синхронизация батча ломается. Следующий батч начинается на сломанном состоянии.
|
||
|
||
## Итог: приоритет причин
|
||
|
||
1. exec() повторяет write(cmd) при таймауте — нельзя дублировать OBD-команды в CAN (первична)
|
||
2. Убрали drainInput() в write() — потеряна синхронизация запрос/ответ
|
||
3. После ATWS не восстанавливают ATE0/ATL0/ATS0 — парсинг ответов ломается
|