Как улучшить стабильность отклика ELM327 на Arduino после проверки настройки с помощью руководства сканера OBD-II?

Я использую Arduino Mega с Bluetooth-адаптером ELM327 для считывания данных с разъёма OBD-II моего автомобиля, а именно оборотов двигателя (PID 010C). Цель — записать данные на SD-карту или отобразить их в режиме реального времени.

Чтобы убедиться, что мой автомобиль и оборудование настроены правильно, я воспользовался этой статьей: Полное руководство по использованию автомобильного диагностического сканера

Я определил правильный порт OBD-II и проверил контакты питания и заземления перед подключением оборудования.

Я инициализировал связь с помощью таких команд, как ATZ, ATE0 и ATSP0.

Я подключил ELM327 через Bluetooth (HC-05) к Serial1 Arduino Mega.

Отправлены следующие AT-команды:

Serial1.print("ATZ\r");     // Сброс
Serial1.print("ATE0\r");    // Эхо выключено
Serial1.print("ATSP0\r");   // Автоматический выбор протокола
Serial1.print("010C\r");    // Запрос оборотов двигателя
Occasionally received a valid response like:
41 0C 1A F8 → ((0x1A * 256) + 0xF8) / 4 = 1720 RPM.

Но ответы непоследовательны: иногда я получаю НЕТ ДАННЫХ, неполные байты или вообще ничего. Я подозреваю, что либо проблемы со временем, либо я неправильно читаю буфер.

Нужно ли ждать подсказку > от ELM327, прежде чем отправлять следующую команду? Если да, то как лучше всего это сделать с помощью кода Arduino?

Мой код Arduino:

#include <SoftwareSerial.h>

SoftwareSerial elmSerial(10, 11); // RX, TX для HC-05 (при необходимости настройте)

void setup() {
  Serial.begin(9600);     // Монитор
  elmSerial.begin(9600);  // ELM327 по умолчанию

  delay(1000);
  sendCommand("ATZ\r");
  sendCommand("ATE0\r");
  sendCommand("ATSP0\r");
}

void loop() {
  sendCommand("010C");  // Запросить RPM
  delay(2000);          // Ожидание между запросами
}

void sendCommand(String cmd) {
  elmSerial.print(cmd + "\r");
  delay(100);

  while (elmSerial.available()) {
    char c = elmSerial.read();
    Serial.print(c); // Вывод на последовательный монитор
  }
}

, 👍1

Обсуждение

Вопрос отредактирован, добавлен мой код для Arduino. Спасибо., @tepalia

Пожалуйста, добавьте также (текстовую(!) копию) вывода в Serial Monitor. Знаете ли вы, что SoftwareSerial не может принимать и отправлять данные одновременно? Ещё один совет: пожалуйста, расширьте вывод до Serial.print(c, HEX);, чтобы сделать видимыми нулевые байты, поскольку сообщения являются двоичными., @the busybee


1 ответ


1

Вы очень близки! Вы правильно настраиваете ELM327 и отправляете правильные команды, но непоследовательные ответы и сообщение «НЕТ ДАННЫХ», вероятно, связаны с проблемами синхронизации и неполным считыванием ответа ELM327 перед отправкой следующей команды.

Вот решение:

  1. Дождитесь приглашения

ELM327 всегда заканчивает свой ответ символом >. Читайте, пока не увидите это.

  1. Избегайте фиксированных задержек — ждите, пока ответ будет готов

Используйте тайм-аут, чтобы не застрять навсегда, если что-то пойдет не так, но в противном случае читайте, пока не появится >.

Обновленный код:

void sendCommand(String cmd) {
  elmSerial.print(cmd + "\r");

  unsigned long startTime = millis();
  String response = "";

  while (millis() - startTime < 2000) { // тайм-аут 2 секунды
    while (elmSerial.available()) {
      char c = elmSerial.read();
      response += c;

      if (c == '>') {
        Serial.print(response); // Печатать только после получения полного ответа
        return;
      }
    }
  }

  Serial.println("Timeout or incomplete response:");
  Serial.println(response);
}
,