0
votes

I am very new to Arduino and this is my very first topic here. I am currently working on car's CAN BUS (500,000bps) communication in order to read and translate the CAN message real time. The UNO together with MCP2515 are connected to the car OBD2 port in order to sniff all supported PID data and the available output are now printed out and it looks promising enough (attached picture). However, I experienced frequent data loss, even though there is the delay of 5 seconds to read the next loop of data. I did try searching but never get any closer to the proper solution. Is this situation is called either Race Condition or data overflow? or I have to take a look at buffer size of transmitted data?

All source file and sketch are referred to https://github.com/sandeepmistry/arduino-OBD2.

Here is the sketch I used (libraries\OBD2-0.0.1\examples\OBD2_01_SupportedPIDs); Please see the result of printout attached.

[#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

1
No idea what these ODB libs do but are they interrupt or DMA driven internally? If they are based on polling, then you can obviously not have a bunch of printf and icky busy-delays between reads or you'll get buffer overruns in no time. A CAN package with 11 bit identifier and 500kbps takes at most 222us to receive.Lundin

1 Answers

0
votes

Upgrading from a UNO to a Mega2560 solved my problems. Now my sketches upload much faster and the frequent crashes have disappeared. Clearly, the UNO has insufficient memory to cope with a can-bus shield.