CAN Bus IDs
There are two types of CAN Bus IDs. In the first version of the CAN Bus spec (2.0A) the IDs were made up of 11 bits. These are also known as base frame format messages. This allows for message IDs between 0x000 and 0x7FF. Which works out to be 2048 possible CAN IDs.
Binary, Decimal and Hex representation of the max 11 bit ID |
Binary, Decimal and Hex representation of the max 29 bit ID |
11 bit code example
Let's take a look at a very simple example of using an MCP2515 CAN controller with an Arduino and 11 bit CAN IDs. I am using a Seeed Studio CAN-BUS Shield but the MCP2515 is just an SPI chip that can be wired up with minimal external components.
In this 11 bit example I am using a CAN ID of 0x07B in hex (123 in decimal).
Here you can see my receiver Arduino is receiving CAN messages with an ID of 123.
29 bit code example
Next let's look at an example of sending 29 bit CAN IDs. In this example I am using a CAN ID of 0x17F8140E in hex (or 402134030 in decimal).
Here you can see my receiver Arduino is receiving CAN messages with an ID of 402134030.
sendMsgBuf format
The key piece of this example code is the sendMsgBuf function. This function is part of theMCP_CAN_lib. This is where messages are flagged as 11 bit or 29 bit.
11 bit: CAN.sendMsgBuf(0x07B, 0, 8, canMsg);
29 bit: CAN.sendMsgBuf(0x17F8140E, 1, 8, canMsg);
The format for this function is sendMsgBuf(can_id, id_type, dlc, data_buf)
can_id - id number for your message in hex or decimal.
id_type - flag for 11 or 29 bit message id. 0=11bit, 1=29bit
dlc - Number of bytes in the message data
data_buf - The data transmitted in the message.
If you are going to try out these examples you should download Cory Fowler's fork of the MCP_CAN_lib.
Resources
If you are going to try out these examples you should download Cory Fowler's fork of the MCP_CAN_lib.
Resources
Hallo Matt,
ReplyDeleteI have an identifier xxxxxxx.
the results in an hexa code 00 01 02 03 04 05 06 07 for example
Is it possible to write a program to get the correct values from the code or decrypt the code in Arduino Software
For example a EngineRpm or something.
best regards
Yes that is definitely possible. The hard part is tracking down which can id has the rpm data. Look for a can id that has data that changes with the engine rpm. Once you find the right can id you have to figure out how the data is stored in the message. Each of the 8 bytes in a can message can only store a value between 0-255 decimal or 00-FF hex. RPM data will range from a minimum of 0 to a max of probably 9999. Since that number will be bigger than 255 it will probably be spread across two or more bytes. How this is done really varies from manufacturer to manufacturer. Sometimes two bytes are multiplied together. Could be each digit is a separate byte (though that is somewhat wasteful and unlikely). You have to play around with the numbers until you get what looks like a reasonable value and then compare that to what you are seeing on your gauges.
DeleteThanks for your fast answer. I have the can ID and i get the HEX code exactly for RPM of Engine.
ReplyDeleteNow I have to encode the HEX. That's very difficult and I don't find anything about it how to write a program to get the real RPM out of the HEX code..:(
If you will send me some of the rpm CAN data I'll take a look at it and see if I can figure anything out.
DeleteID: 0x280
ReplyDeleteHEX: 09 22 28 0A 22 00 22 22
now i need the result what is the rpm in real DEZ. is there no standard program that i can figure out the values?
best regards
byte 2 and byte 3 is where the rpm data should stay
ReplyDeletethanks a lot for your help
Can you post like 5 or 10 of the CAN messages so I can see the data changing?
Deletei will look for more messages tomorrow and then I'll send you some..
ReplyDeletegreets..
Hello, thank you for your nice blog. I have the problem, when i read can-bus using can-bus shield and arduino, the messages for steering wheel buttons(which control audio system) absolutely the same, another messages have uniq ID's, but for joystick and audio control for each press different button i receive the same message, can you tell me please what can be wrong? I have volvo s80 II 2008. Thank you
ReplyDeleteIt would be helpful if you can post some data to look at. Is it possible the messages have the same can ID but different data in the message?
DeleteData is the same, can ID the same too. Maybe i found wrong message, this message can be just response from HU? I will send the message today, later. Thank you
DeleteYeah sounds like you might have the wrong CAN id. Probably related but maybe there is a different id with the actions you are looking for.
Delete
ReplyDeleteDear Matt McMillan!!!
I want to http://ru.aliexpress.com/item/MCP2515-CAN-Bus-Module-TJA1050-Receiver-SPI-Module-for-Arduino/32391372405.html purchase this module !! Do you think it will work ?
Yes that should work.
DeleteDo you have quartz on 16 MHz, but on the Chinese clone at 8 MHz. I'm confused about this point.
DeleteOh interesting. I didn't look closely at the crystal. Yeah you are right it is an 8 MHz part on the clone. I just checked the data sheet for the MCP2515 and an 8 MHz resonator is acceptable with the right capacitors. Look at page 56 in this document: http://ww1.microchip.com/downloads/en/DeviceDoc/21801G.pdf
DeleteHello Matt McMillan,
ReplyDeleteI have successfully communicated two arduino using CAN bus by taking your tutorial as a reference.
Now i want to make communication between three arduino using CAN bus.
Please guide me, How should i do it?
Additional devices can just be connected into the CAN bus. You can T off of the twisted CAN-H and CAN-L wire pair. The only difference is additional devices don't need the termination resistor. All devices need to share a common ground.
DeleteThank you for your guidance. I will try it.
ReplyDeleteHello Matt,
ReplyDeleteI have succesfully communicated a CAN bus shield with an Arduino Mega2560 following one of yours tutorials, now i'm trying to receive messages from a controller that uses two messages in the extended frame format. My problem is that apparently the can bus shield can´t separate well the ID bits of the data bits, so do you know if i have to write an extra code for this or its supposed that the typical receive example should work for this?
Best Regards!
Hello Matt,
ReplyDeleteI have succesfully communicated the CAN bus shield with an arduino Mega2560 following one of yours tutorials, now i have a controller that delivers two types of messages in the extended frame format. My problem is that the receive code that you recommend in other tutorial apparently can´t realize when a new message is arriving, so i have a wrong ID an wrong data bytes, do you know if i have to make some changes in the code for 29 bits identifiers meassages?
Best regards!
hello ,
ReplyDeletei am working on receiving a data from an ECU and i have a tool called busmaster connected with vector can case and i want to use arduino plus shield i have one which has a clock of 8MHZ . th e ids i am getting are wrong data length also and data all of them are completely different than what gives busmaster can you help me please.
hi, i have this code, how i can convert in 29 bit?
ReplyDeletevoid loop()
{
tCAN message;
message.id =0x0010A152; //formatted in HEX
message.header.rtr = 1;
message.header.length = 7; //formatted in DEC
message.data[0] = 0xAB ;
message.data[1] = 0x3F;
message.data[2] = 0x93;
message.data[3] = 0x00; //formatted in HEX
message.data[4] = 0x00;
message.data[5] = 0x00;
message.data[6] = 0x00;
mcp2515_bit_modify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0),1);
mcp2515_send_message(&message);
delay(100);
thanks again
remove this "mcp2515_send_message(&message);" and add this line:
ReplyDelete"mcp2515_send_message_J1939(&message);"
Matt, What does your receive code look like? I am using readMsgBuf, but I am having problems receiving 29 bit Identifiers...
ReplyDeleteLooks like the MCP_can library has been updated quite a bit. I haven't used the new version yet. Have you tried the example code included with the library?
Deletei am facing the same issue, unable to read a extended CAN ID message
Deletehowever, able to send extended CAN ID messages
i am using sparkfun CAN shield with Arduino UNO and a CAN single wire to double wire converter to talk to a custom engine ECU
Hello
ReplyDeleteSomebody can help me whether this code is correct or not?
#include
#include
const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
void setup()
{
Serial.begin(115200);
if(CAN.begin(CAN_100KBPS) ==CAN_OK) Serial.print("can init ok!!\r\n");// init can bus, baudrate: 100k
else Serial.print("Can init fail!!\r\n");
}
void loop()
{
// send data:
unsigned char stmp1[4] = {0x07, 0x00, 0x00, 0x00};//AC key on
CAN.sendMsgBuf(0x575, 0, 4, stmp1);
delay(100); // send data per 100ms
unsigned char stmp2[4] = {0x60, 0x60, 0x00, 0x00}; //button illumination
CAN.sendMsgBuf(0x635, 0, 4, stmp2);
delay(100); // send data per 100ms
}
Anyone figure out how to RECEIEVE 29xtd bit IDs?
ReplyDeleteThanks for posting the example on extended bits. Just sent you a donation. I was only off by one change but could have taken hours of looking and hitting your site on my first search saved me lots of headaches. I can now fully control an Audi MIB Navigation system with my own computer program :D
ReplyDeleteWow. Very cool. Thanks for the donation!
DeleteJust looking at your code examples above, does that code work for reading 29bit frames? I am about to start looking at my vehicle to replace the sat-nav and need to read 29bit/extended frames.
ReplyDeleteThanks in advance
D