CAN.getCANId()

Hi,

I am trying to understand the usage of CAN bus in Arduino. I was referring to a manual in which the author has used the function CAN.getCanId() function in the following manner:

if (CAN_MSGAVAIL == CAN.checkReceive()
 {
 CAN.readMsgBuf(&len, buf);
 unsigned long canId = CAN.getCanId();

 if (canId >> 19 == 760) {
 Serial.println("-----------------------------");
 Serial.println("get data from ID: ");
 Serial.println(canId);
 Serial.print("Variable ID= ");
 Serial.println(canId >> 19);
 Serial.print("Source node ID= ");
 Serial.println((canId >> 10) & 0x7F);
 Serial.print("Transfer ID= ");
 Serial.println(canId & 0x7);
 //Serial.println(millis()>>9);

 for (int i = 0; i < len; i++)
 {
 Serial.print(buf[i]);
 Serial.print("\t");
 val = map(val, 0, 255, 0, 180);
 myservo.write(val);
 if (ledON && i == 0)
 {
 digitalWrite(LED, buf[i]);
 ledON = 1;
 }
 }
 Serial.println();
 }
 }

He is receiving the value from CAN bus and controlling a servo motor with that.

The output he has given as :


get data from ID:
398722057
Variable ID= 760
Source node ID= 1
Transfer ID= 1
1

I understand 760 is my data type id from my sending CAN device and 1 is the value(I marked bold the above both in output)

But my question arises with getCanId() function! What does this function receive? I checked the below link: http://www.86duino.com/?p=8017. It stated it would fetch ID.

But in his code, he is extracting data as well from using the function. Will this function return only ID? if so how is it possible to extract data? Or will it receive the entire CAN frame on the CAN port?

Arduino: Olimexino was used.

Any pointers would be highly helpful.
Thank you

thanks and regards
Niranjan

A CAN packet looks a bit like this ( ESP32 CAN library ):

rx_frame.FIR.B.FF = CAN_frame_std;
rx_frame.MsgID = xServo_EOT.MsgID;
rx_frame.FIR.B.DLC = xServo_EOT.DLC;
rx_frame.data.u8[0] = xServo_EOT.Servo_EOT;
rx_frame.data.u8[1] = xServo_EOT.p4; // send all '0'
rx_frame.data.u8[2] = xServo_EOT.p4;
rx_frame.data.u8[3] = xServo_EOT.p4;
rx_frame.data.u8[4] = xServo_EOT.p4;
rx_frame.data.u8[5] = xServo_EOT.p4;
rx_frame.data.u8[6] = xServo_EOT.p4;
rx_frame.data.u8[7] = xServo_EOT.p4;
ESP32Can.CANWriteFrame(&rx_frame);

A CAN ID (MsgID) can be either 11 or 29 bits, depending on the used standard. From the code the CAN ID shift sizes, the code is using the CANID extended, 29 bits. rx_frame.FIR.B.FF declares the 11 bit frame size. From what I can see a 29 bit ID is being used to supply data.

Note, the CAN ID also settles race conditions. The CAN ID with the most leading digits, transmitting to the NODE controller wins and is processed first. The NODE controller has a data queue so it can receive more than one CAN packet at a time. I find that 3-5 queues is all that is needed for efficiency.

All CAN devices listen, when the ID comes in, if the ID is not a match the receiving node stops processing the rest of the CAN message and goes back to listening for other ID's

A CAN frame can send 8 bytes.

I use the CAN ID to identify the device and to contain an instruction. I use the data for data transfers.

I have become quite fond of the CAN Buss over serial since figuring out how to use it.

Hi, Thank you for your reply. Yes, the sending device has a 29-bit identifier so does my device. I saw this code in Arduino but I need to use this function in my embedded platform.

But I am not able to understand what this CAN.getCANID() does? here CAN is can port number - I understand this getCANId is giving a value but is there any masking done or what would be equivalent hex value for this?

398722057 and how 398722057 >> 19 is 760 ? if I understand this I can fix my problem actually!

Board:: https://www.arduino.cc/en/Main/ArduinoBoardDiecimila

Any pointers? Thank you Thanks and Regards Niranjan

a >> b means shifting the bit-pattern of a, b times to the right and filling in 0 from the left (if a is unsigned).

The binary representation of desimal 398722057 is 00010111 11000100 00000100 00001001. Shift the bits 19 times to the right and you get 00000000 00000000 00000010 11111000, which is desimal 760.

Ha!! yeah. I figured where I went wrong. While making hex to decimal conversion I wrote '10' instead of 'a' and I was wrong. Thank you