How to combine the SID and EID for mcp2515 CAN communication?

I am using the Arduino to control multi-motor devices through the MCP2515 CAN interface library:

It works brilliantly when I use the standard data frame (11-bit):

  canMsg.can_id  = 0x102;         //can id  
  canMsg.can_dlc = 4;             //data length  
  canMsg.data[0] = 0x00;          
  canMsg.data[1] = 0x01;          
  canMsg.data[2] = 0x01;           
  canMsg.data[3] = 0x29;          
  mcp2515.sendMessage(&canMsg);

But now I need to use the extended data frame (29-bit) to send the data. Instead of providing me with a complete can id, my manual only gives me the SID and EID such as:
SID: 0b00000001000
EID: 0x00010
RTR: 1
The structure of the can id in MCP2515 library is:

uint32_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */

I try to find the definition of the can_id but it is difficult for me to understand:

  • Controller Area Network Identifier structure
  • bit 0-28 : CAN identifier (11/29 bit)
  • bit 29 : error message frame flag (0 = data frame, 1 = error message)
  • bit 30 : remote transmission request flag
  • bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)

Does anyone know how to put the SID, EID and RTR together to form the can_id for MCP2515 CAN communication?

hansng:

uint32_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */

I try to find the definition of the can_id but it is difficult for me to understand:

  • Controller Area Network Identifier structure
  • bit 0-28 : CAN identifier (11/29 bit)
  • bit 29 : error message frame flag (0 = data frame, 1 = error message)
  • bit 30 : remote transmission request flag
  • bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)

hansng:
But now I need to use the extended data frame (29-bit) to send the data. Instead of providing me with a complete can id, my manual only gives me the SID and EID such as:
SID: 0b00000001000
EID: 0x00010
RTR: 1

somthing like this you mean?

#define Is_Extended 0x80000000UL
#define Set_RTR 0x40000000UL
#define Is_ErrorFrame 0x20000000UL

uint32_t id = 0x102; //change the ID to whatever you need

//standard ID, no RTR, not an error frame
canMsg.can_id  = (~Is_Extended)&((~Set_RTR)&((~Is_ErrorFrame)&id));

//EXTENDED ID, no RTR, not an error frame
canMsg.can_id  = Is_Extended|((~Set_RTR)&((~Is_ErrorFrame)&id));

//EXTENDED ID, RTR, not an error frame
canMsg.can_id  = Is_Extended|Set_RTR|((~Is_ErrorFrame)&id);

hope that helps...

sherzaad:
somthing like this you mean?

#define Is_Extended 0x80000000UL

#define Set_RTR 0x40000000UL
#define Is_ErrorFrame 0x20000000UL

uint32_t id = 0x102; //change the ID to whatever you need

//standard ID, no RTR, not an error frame
canMsg.can_id  = (~Is_Extended)&((~Set_RTR)&((~Is_ErrorFrame)&id));

//EXTENDED ID, no RTR, not an error frame
canMsg.can_id  = Is_Extended|((~Set_RTR)&((~Is_ErrorFrame)&id));

//EXTENDED ID, RTR, not an error frame
canMsg.can_id  = Is_Extended|Set_RTR|((~Is_ErrorFrame)&id);




hope that helps...

Thank you very much for your reply.
The uint32_t id =0x102 is the address for the old device. I am going to use my system to control a new multi-motor device so that's not the address I want.
For the new device, they don't provide me an intuitional can_id, but give me the components of it ,such as the SID and EID. However, I do not quite understand the relationship between them.
Since the SID is 0b00000001000, which is 11 bits, and the EID is 0x00010, which can be 18 bits, does it mean that the 29 bit ID is the combination of them two?
such as:

ID = (SID << 18) | EID

and the 32 bit can_id is:

can_id = (ID << 3)|(EFF << 2)|(RTR  << 1) | ERR

so it sounds like this

  • Controller Area Network Identifier structure
  • bit 0-28 : CAN identifier (11/29 bit)
  • bit 29 : error message frame flag (0 = data frame, 1 = error message)
  • bit 30 : remote transmission request flag
  • bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)

can be re-written as

  • Controller Area Network Identifier structure
  • bit 0-10 : SID (11 bits)
  • bit 10-28 : EID (18 bits. set to 0 if frame format flag =0, else set value accordingly)
  • bit 29 : error message frame flag (0 = data frame, 1 = error message)
  • bit 30 : remote transmission request flag
  • bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)

and you seem to have the hang of bit shifting so I'll let you have a go from here! :wink:

sherzaad:
so it sounds like this

  • Controller Area Network Identifier structure
  • bit 0-28 : CAN identifier (11/29 bit)
  • bit 29 : error message frame flag (0 = data frame, 1 = error message)
  • bit 30 : remote transmission request flag
  • bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)

can be re-written as

  • Controller Area Network Identifier structure
  • bit 0-10 : SID (11 bits)
  • bit 10-28 : EID (18 bits. set to 0 if frame format flag =0, else set value accordingly)
  • bit 29 : error message frame flag (0 = data frame, 1 = error message)
  • bit 30 : remote transmission request flag
  • bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)

and you seem to have the hang of bit shifting so I'll let you have a go from here! :wink:

It's much clearer.
The can_id then should be:

#define EFF 1 //use the 29 bit extended id
#define ERR 0 //the manual hasn't mentioned the error bit, but I assume it should be 0 when I send and receive data
//RTR, EID and SID depend on the control commands.
can_id = (EFF<<31)|(RTR<<30)|(ERR<<29)|(EID<<11)|SID;

I will go to have a try. Thank you very much for your help.

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