MCP2515 CANBus filtering

Hi,

this post has already helped me a lot to understand the mask and filter features but I still don't fully understand the mask. I understand that the mask tells the controller to check certain bits. But the reason you have to use 0x7FF in both mask's is a mystery to me.

What would happen is you used other values than 0x7FF? Do you have to use the same value in both mask's? or can you use different ones in each mask?

KVNMRSMN:
Hi,

this post has already helped me a lot to understand the mask and filter features but I still don’t fully understand the mask. I understand that the mask tells the controller to check certain bits. But the reason you have to use 0x7FF in both mask’s is a mystery to me.

What would happen is you used other values than 0x7FF?

The bits of the mask that are zero will not be checked against the filter values.

If I were to use 0x7F0 as the mask and I had 0x125 and 0x137 as filter values, I would see any message that has an ID beginning with 0x120 and 0x130, the last nibble is ignored.

KVNMRSMN:
Do you have to use the same value in both mask’s? or can you use different ones in each mask?

No, you do not have to keep them the same, but if you do use different values, you will need to be aware of the bucket bit and how that bit effects received data. You will also need to be aware that mask 0 and filters 0 and 1 are for receive buffer 0 and mask 1 and filters 2, 3, 4, and 5 are for receive buffer 1.

Thank you for the reply, it explains the things I wasn't sure about.

One last question, if I use 0x7FF in both masks it is going to check all bits, right? Or are there still bits the controller won't check?

KVNMRSMN: Thank you for the reply, it explains the things I wasn't sure about.

One last question, if I use 0x7FF in both masks it is going to check all bits, right? Or are there still bits the controller won't check?

Depends..

For standard IDs, the filtering core can check against the first two data bytes, so instead of 0x07FF0000, the mask could be 0x07FFFFFF which would include the first two data bytes in the filter check, applications for this are rare and limited though.

For extended IDs, the filtering core can only check against the ID, so a mask would be 0x1FFFFFFF to check all 29 bits of the ID.

Hello.

First time posting here! I’m using an Arduino Uno, SPI Can-Bus Shield V1.2, mcp_can.

Masks and filters are working to get only the ID (STD) I want but, I also need to filter the first data byte. My ECU sends message rows using the first byte and I only want to get message rows with 0,1, and 2 in the first byte.

I understand that the MCP2515 can also filter on two bytes but I haven’t been able to configure those to work. Here is one example I’ve tried in the Sketch:

CAN0.init_Mask(x,0,0x0FFFFF00);
CAN0.init_Filt(0,0,0x0???0000);
CAN0.init_Filt(1,0,0x0???0100);
CAN0.init_Filt(2,0,0x0???0200);

Does the 2515 need to be set to a mode other that NORMAL to allow defining the two byte filters?

Thank you for the assistance.

I had been using an 2014 version on mcp_can. Trying the latest.

Wirless63: [...] I understand that the MCP2515 can also filter on two bytes but I haven't been able to configure those to work. Here is one example I've tried in the Sketch:

CAN0.init_Mask(x,0,0x0FFFFF00); CAN0.init_Filt(0,0,0x0???0000); CAN0.init_Filt(1,0,0x0???0100); CAN0.init_Filt(2,0,0x0???0200); ...

Looks correct, but 0x07FFFF00 would be more appropriate for your mask.

Wirless63: Does the 2515 need to be set to a mode other that NORMAL to allow defining the two byte filters? [...]

Actually, going off bus has proven to be the most reliable way of setting masks and filters and I have the library setup so that the begin() function initializes the MCP2515 in loopback mode. In the examples where masks and filters are set, going to NORMAL mode is the final step before leaving the setup routine in the sketch.

@coryjfowler, thank you for your awesome library.

Please help me understand filters and masks.

Lets's say I need to receive only standard IDs from 7E8 to 7EF and 7DF. With the range 7E8 to 7EF we are ignoring last 3 bits, so the mask will be 0x07F80000 and the filter will be 0x07E80000.

For the value 7DF mask will be 0x07FF0000 (we need to check all bits) and the filter will be 0x07DF0000.

It works.

However, I spent some time trying to understand your previous message:

coryjfowler:        111 1111 1111 = 0x7FF entered in as 0x1FFC0000  MASK: 111 1111 1111 00 0000 0000 0000 0000 FILTER: 111 1110 1000 00 0000 0000 0000 0000

This above scenario will accept ONLY the 0x7E8 identifier.

According this my mask for the range should be

0x7F8 = 111 1111 1000
(adding 2 unused bits and 2 bytes for data filtering) 00 0000 0000 0000 0000
111 1111 1000 00 0000 0000 0000 0000 = 1 1111 1110 0000 0000 0000 0000 0000 = 0x1FE00000

So, the mask should be 0x1FE00000. And so on with filters. But it doesn't work.

Can you tell me what I am missing and what is the right way to calculate masks/filters? I assume it will be the first one as it works.

If the first option as far as I understand 2 bits were moved to the beginning and in the second they are in the middle.

Thanks.

Starina: @coryjfowler, thank you for your awesome library.

Please help me understand filters and masks.

Lets's say I need to receive only standard IDs from 7E8 to 7EF and 7DF. With the range 7E8 to 7EF we are ignoring last 3 bits, so the mask will be 0x07F80000 and the filter will be 0x07E80000.

For the value 7DF mask will be 0x07FF0000 (we need to check all bits) and the filter will be 0x07DF0000.

It works.

This all sounds correct.

Basically: M0 = 0x07FF0000 F0 = F1 = 0x07DF0000

M1 = 0x07F80000 F2 = F3 = F4 = F5 = 0x07E80000

Starina: However, I spent some time trying to understand your previous message:

According this my mask for the range should be

0x7F8 = 111 1111 1000
(adding 2 unused bits and 2 bytes for data filtering) 00 0000 0000 0000 0000
111 1111 1000 00 0000 0000 0000 0000 = 1 1111 1110 0000 0000 0000 0000 0000 = 0x1FE00000

So, the mask should be 0x1FE00000. And so on with filters. But it doesn't work.

Can you tell me what I am missing [...]

Yes, you are missing the date; that is over three years old and no longer applies. The filtering examples included with the library reflect what is current.

coryjfowler: Yes, you are missing the date; that is over three years old and no longer applies. The filtering examples included with the library reflect what is current.

Oh, thanks! I really didn't notice it.

While playing with my car can I got another question. Is it possible to make MCP2515 to throttle messages? I mean to configure it in some way to receive some PIDs lets say once per second or once per 10 seconds.

Right now I do it using code. I save the latest received message in the settings array

msgId   Delay   LastReceivedTime
0x001   10000  11000
0x002   60000  12000
0x003   10000  13000

and check with the next message : I search by it's id and check if (millis() - lastReceivedTime > Delay) then I accept the message and update lastReceivedTime.

Is there a way to do it more nicely?

Thank you.

Mr. Fowler,

Thank you for the response on Jan 16th. It took a while but, I did manage to get the mask and filter to work perfectly! :)

I'm now struggling with ".sendMsgBuf()". I'm trying to find a way to send custom bytes and rxBuf[n] within sendMsgBuf(). Example: CAN1.sendMsgBuf(0x7E8, 0, 3, (0x41, 0x0A, rxBuf[1])). I may have to revert to serial between two Unos with CAN shields so I can customize the serial messages.

Thank you for the libraries and the support on the forum!

Wirless63: I'm now struggling with ".sendMsgBuf()". I'm trying to find a way to send custom bytes and rxBuf[n] within sendMsgBuf(). Example: CAN1.sendMsgBuf(0x7E8, 0, 3, (0x41, 0x0A, rxBuf[1])).

You would want to do something like the below:

byte txBuf[] = {0x41, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

setup(){

  //Setup stuff
  [...]

}


loop(){

  // Loop stuff
  [...]

  
  txBuf[2] = rxBuf[1];
  CAN1.sendMsgBuf(0x7E8, 0, 3, txBuf);

}

Thank you Mr. Fowler.

I think I understand where you are going with this.

Being a Newbie, your assistance is much appreciated!

You're the Man!

Worked fine once I figured out the substitution of the byte correctly. Starts at "0" not "1". Such a rookie mistake.

Thanks again Mr. Fowler.

To avoid errors you need to set all masks and filters (otherwise it can be rubbish there)

CAN0.init_Mask(0,0,0x07FF0000);                // Init first mask...
CAN0.init_Filt(0,0,0x02040000);                // Init first filter...
CAN0.init_Filt(1,0,0x02040000);                // Init second filter...
  
  CAN0.init_Mask(1,0,0x07FF0000);                // Init second mask... 
  CAN0.init_Filt(2,0,0x02040000);                // Init third filter...
  CAN0.init_Filt(3,0,0x02040000);                // Init fouth filter...
  CAN0.init_Filt(4,0,0x02040000);                // Init fifth filter...
  CAN0.init_Filt(5,0,0x02040000);                // Init sixth filter...

Also, read starting from the middle of this topic as the first post is already outdated.
Examples are also correct.

Starina: To avoid errors you need to set all masks and filters (otherwise it can be rubbish there)

CAN0.init_Mask(0,0,0x07FF0000);                // Init first mask...
CAN0.init_Filt(0,0,0x02040000);                // Init first filter...
CAN0.init_Filt(1,0,0x02040000);                // Init second filter...
  
  CAN0.init_Mask(1,0,0x07FF0000);                // Init second mask... 
  CAN0.init_Filt(2,0,0x02040000);                // Init third filter...
  CAN0.init_Filt(3,0,0x02040000);                // Init fouth filter...
  CAN0.init_Filt(4,0,0x02040000);                // Init fifth filter...
  CAN0.init_Filt(5,0,0x02040000);                // Init sixth filter...

Also, read starting from the middle of this topic as the first post is already outdated. Examples are also correct.

Thanks! In the meantime I also figured this out.

Excuse me for asking the question to early, I will delete it.

Hello,

Am trying to set mask and filter for my master and slave CAN bus.

Am trying to use

CAN0.init_Mask(0,0,0x0F810000); // Init first mask… CAN0.init_Filt(0,0,0x01810000); // Init first filter… CAN0.init_Filt(1,0,0x02810000); // Init second filter…

CAN0.init_Mask(1,0,0x0F810000); // Init second mask… CAN0.init_Filt(2,0,0x03810000); // Init third filter… CAN0.init_Filt(3,0,0x04810000); // Init fourth filter…

This is my mask and filter on the receiver side, could you please tell me the address i have to use in the sender side.