Code stuck on CAN.endPacket()

I have a MCP2515 CANshield connected to an Uno.
I wrote a code that runs fine when connected to my car.
But when running the code outside the car it gets stuck on the “CAN.endPacket();” command.
I’m afraid my code getting stuck if there will be some connection problem in the car.

I could not find how to add a timeout to this command.

#include <CAN.h>

void setup() {
  Serial.begin(9600);
  Serial.println("Hi");
  if (!CAN.begin(1000E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  } 
  Serial.println("CAN connected");
}

void loop() {
  CAN.beginPacket(0x7df, 8);
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0d); // car speed
  Serial.print("this works");
  CAN.endPacket();
  Serial.print("never getting here");
}

I found an issue similar to this in the github: esp32 hangs on CAN.endPacket(); · Issue #10 · sandeepmistry/arduino-CAN · GitHub but the code for MCP2515 is not the same as for the ESP32 and I was not able to figure how to fix the code by myself.

I saw that the can.h was not updated for the last 4 year, and that there are allot of forks of it.

How can I add a timeout for the command?
Is there a fork that fixes this problem?

I kept working on this and found how to fix the code (based on the remareks in the issue):
in MCP2515.cpp change the functio to this:

int MCP2515Class::endPacket()
{
  if (!CANControllerClass::endPacket()) {
    return 0;
  }

  int n = 0;

  if (_txExtended) {
    writeRegister(REG_TXBnSIDH(n), _txId >> 21);
    writeRegister(REG_TXBnSIDL(n), (((_txId >> 18) & 0x07) << 5) | FLAG_EXIDE | ((_txId >> 16) & 0x03));
    writeRegister(REG_TXBnEID8(n), (_txId >> 8) & 0xff);
    writeRegister(REG_TXBnEID0(n), _txId & 0xff);
  } else {
    writeRegister(REG_TXBnSIDH(n), _txId >> 3);
    writeRegister(REG_TXBnSIDL(n), _txId << 5);
    writeRegister(REG_TXBnEID8(n), 0x00);
    writeRegister(REG_TXBnEID0(n), 0x00);
  }

  if (_txRtr) {
    writeRegister(REG_TXBnDLC(n), 0x40 | _txLength);
  } else {
    writeRegister(REG_TXBnDLC(n), _txLength);

    for (int i = 0; i < _txLength; i++) {
      writeRegister(REG_TXBnD0(n) + i, _txData[i]);
    }
  }

  writeRegister(REG_TXBnCTRL(n), 0x08);

  bool aborted = false;

  const uint8_t TIMEOUTVALUE = 50;
  uint8_t uiTimeOut = 0;
 
  while ( (readRegister(REG_TXBnCTRL(n)) & 0x08) && (uiTimeOut < TIMEOUTVALUE) ){
    if (readRegister(REG_TXBnCTRL(n)) & 0x10) {
      // abort
      aborted = true;
      modifyRegister(REG_CANCTRL, 0x10, 0x10);
    }

    yield();
    uiTimeOut++;
  }

  if(uiTimeOut == TIMEOUTVALUE) {return -1;} // get tx buff time out 
	
  if (aborted ) { //his
    // clear abort command
    modifyRegister(REG_CANCTRL, 0x10, 0x00);
  }

  modifyRegister(REG_CANINTF, FLAG_TXnIF(n), 0x00);

  return (readRegister(REG_TXBnCTRL(n)) & 0x70) ? 0 : 1;
}

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