【问题标题】:Data loss during communication via car's CAN bus (Arduino Uno + MCP2515)通过汽车的 CAN 总线进行通信期间的数据丢失 (Arduino Uno + MCP2515)
【发布时间】:2021-01-09 17:30:00
【问题描述】:

我对 Arduino 很陌生,这是我在这里的第一个主题。我目前正在研究汽车的 CAN BUS (500,000bps) 通信,以便实时读取和翻译 CAN 消息。 UNO 与 MCP2515 一起连接到汽车 OBD2 端口,以便嗅探所有支持的 PID 数据,现在打印出可用的输出,看起来很有希望(附图)。然而,我经历了频繁的数据丢失,即使有 5 秒的延迟来读取下一个循环的数据。我确实尝试过搜索,但从未接近正确的解决方案。这种情况称为竞争条件还是数据溢出?或者我必须看看传输数据的缓冲区大小?

所有源文件和草图都参考https://github.com/sandeepmistry/arduino-OBD2

这是我使用的草图(libraries\OBD2-0.0.1\examples\OBD2_01_SupportedPIDs); 打印结果见附件。

[#include <CAN.h> // the OBD2 library depends on the CAN library
#include <OBD2.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println(F("OBD2 data printer"));

  while (true) {
    Serial.print(F("Attempting to connect to OBD2 CAN bus ... "));

    if (!OBD2.begin()) {
      Serial.println(F("failed!"));

      delay(1000);
    } else {
      Serial.println(F("success"));
      break;
    }
  }

  Serial.println();
  Serial.print("VIN = ");
  Serial.println(OBD2.vinRead());
  Serial.print("ECU Name = ");
  Serial.println(OBD2.ecuNameRead());
  Serial.println();
}

void loop() {
  // loop through PIDs 0 to 95, reading and printing the values
  for (int pid = 0; pid < 96; pid++) {
    processPid(pid);
  }
  Serial.println();

  // wait 5 seconds before next run
  delay(5000);
}

void processPid(int pid) {
  if (!OBD2.pidSupported(pid)) {
    // PID not supported, continue to next one ...
    return;
  }

  // print PID name
  Serial.print(OBD2.pidName(pid));
  Serial.print(F(" = "));

  if (OBD2.pidValueRaw(pid)) {
    // read the raw PID value
    unsigned long pidRawValue = OBD2.pidReadRaw(pid);

    Serial.print(F("0x"));
    Serial.print(pidRawValue, HEX);
  } else {
    // read the PID value
    float pidValue = OBD2.pidRead(pid);

    if (isnan(pidValue)) {
      Serial.print("error");
    } else {
      // print value with units

      Serial.print(pidValue);
      Serial.print(F(" "));
      Serial.print(OBD2.pidUnits(pid));
    }
  }

  Serial.println();
}][1]

Printout of sketch OBD2_03_DataPrinter.ino

【问题讨论】:

  • 不知道这些 ODB 库做了什么,但它们是中断还是内部驱动的 DMA?如果它们基于轮询,那么您显然不能在读取之间有一堆 printf 和 icky 忙延迟,否则您将立即获得缓冲区溢出。一个 11 位标识符和 500kbps 的 CAN 包最多需要 222us 才能接收。

标签: arduino arduino-uno can-bus


【解决方案1】:

从 UNO 升级到 Mega2560 解决了我的问题。现在我的草图上传速度更快,频繁的崩溃也消失了。显然,UNO 没有足够的内存来应对 can-bus 屏蔽。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多