Receiving more than 8 bytes from CAN

Hello.
I've been stuck for some time with my project and would greatly appreciate some help. I'm rather far from programming and my brains are boiling already)

I need to read some exact bytes from CAN of my car and use it to calculate and display values like RPM etc.

Engine ECU sends 8 byte long messages, so I have no problem with reading it and dealing with any byte I want. For example, for RPM, I need bytes 5 and 6 from this:
5 62 20 2 B B8

 CAN1.readMsgBuf(&len, rxBuf); // : len = data length, buf = data byte(s)
      rxId = CAN1.getCanId(); 
    }
  }
  if (rxId == moduleIdAnswer && rxBuf[1] == PID[1] && rxBuf[2] == PID[2] && rxBuf[3] == PID[3]) {
    //  tthe above it to get correct bytes for a value.  A = rxBuf[4], B = rxBuf[5], C = rxBuf[6], D = rxBuf[7]
    switch (parameter) {
      case 0:
        // RPM
        retValue = (256 * rxBuf[4] + rxBuf[5]) / 4.0;
        break; 
    }
  }
  return retValue;
}

But another ECU sends messages 18 bytes long. And for my calculation I need byte 18.

This is an example line, that I'm dealing with, excluding the first byte, which I don't know yet, but it doesn't matter:
x 61 22 3 0 0 2 20 0 0 0 34 80 fa 9 0 0 38

I need to be able to use "38" . How do I get it?

Is below correct or I don't understant how buffers work?(

      CAN1.readMsgBuf(&len, rxBuf); // 
      CAN1.readMsgBuf(&len1, rxBuf1); // do I really need &len1 and &len2?... it's still 8 bytes per frame.
      CAN1.readMsgBuf(&len2, rxBuf2);
      
      rxId = CAN1.getCanId(); //
      
      Serial.println("CAN_BUS GET DATA");
      Serial.print("CAN ID: ");
      Serial.println(rxId);
      
      Serial.print("data len = ");
      Serial.println(len);
      //This loops through each byte of data and prints it
      for(int i = 0; i<len; i++)    // print the data
      {
        Serial.print(rxBuf[i]);
        Serial.print("\t");
      }
      
      Serial.print("data len1 = ");
      Serial.println(len1);
      //This loops through each byte of data and prints it
      for(int i = 0; i<len1; i++)    // print the data
      {
        Serial.print(rxBuf1[i]);
        Serial.print("\t");
      }

      Serial.print("data len2 = ");
      Serial.println(len2);
      //This loops through each byte of data and prints it
      for(int i = 0; i<len2; i++)    // print the data
      {
        Serial.print(rxBuf2[i]);
        Serial.print("\t");
      }
     
      Serial.println();
      delay(1000);

  if (rxId == moduleIdAnswer && rxBuf[1] == PID[1] && rxBuf[2] == PID[2]) {
    // A = rxBuf[4], B = rxBuf[5], C = rxBuf[6], D = rxBuf[7], ... O = rxBuf2[0]
    switch (parameter) {
      case 0:
        // ExtTemp
        retValue = (rxBuf2[0] - 40);
        break; 
    }
  }
  return retValue;
}

Sorry for the long post...

A single message longer than 8 bytes implies the use of CAN FD instead of regular CAN.
If you are using a MCP2515 then you won't be able to receive CAN FD messages. Is that what you are using?

Here is an ODB data processing example using the ELMduino library

Right, MCP2515 is the one I have.

Search the ECU documentation for the phrase "CAN FD" or "Flexible Data-Rate". If it really is using CAN FD then you'll need a interface board with a chip such as the MCP2517FD.

If you cannot find any references to CAN FD then the documentation may be referring to multiple 8 byte messages over regular CAN which you have to combine in your code to give a longer message.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.