CanBus Filtering

Please someone can solve this filter for me i want just get the data with id=8CF00400 as highlighted in the picture attached.


// MCP2515 Mask and Filter example for extended CAN message frames.
// Written by Cory J. Fowler (20140717)

/***********************************************************************************
If you send the following extended IDs below to an Arduino loaded with this sketch
you will find that 0x00FFCC00 and 0x00FF9900 will not get in.

   ID in Hex is the same as the Filter in Hex.
   0x00FFEE00
   0x00FFDD00
   0x00FFCC00  This example will NOT be receiving this ID
   0x00FFBB00
   0x00FFAA00
   0x00FF9900  This example will NOT be receiving this ID
   0x00FF8800
   0x00FF7700

   This mask will check the filters against ID bits 23 through 8.
   (Those familiar with J1939 might see why I used this mask.)
    MASK = 0x00FFFF00
   If there is an explicit filter match to those bits, the message will be passed to the
   receive buffer and the interrupt pin will be set.
   
   This example will NOT be exclusive to ONLY the above message IDs, for that a mask such
   as the below would be used: 
    MASK = 0x1FFFFFFF
   
   At the moment, to disable a filter or mask, copy the value of a used filter or mask.
   
***********************************************************************************/


#include <mcp_can.h>
#include <SPI.h>

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];

MCP_CAN CAN0(49);  // Set CS to pin 10

void setup() {
  digitalWrite(53, OUTPUT);
  Serial.begin(115200);
  if (CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK) Serial.print("MCP2515 Init Okay!!\r\n");
  else Serial.print("MCP2515 Init Failed!!\r\n");
  pinMode(2, INPUT);  // Setting pin 2 for /INT input
  CAN0.init_Mask(0, 0, 0x07FFFFFF);
  CAN0.init_Filt(0, 0, 0x02908000);
  CAN0.init_Filt(1, 0, 0x02908000);

  CAN0.init_Mask(1, 0, 0x07FFFFFF);
  CAN0.init_Filt(2, 0, 0x02908000);
  CAN0.init_Filt(3, 0, 0x02908000);
  CAN0.init_Filt(4, 0, 0x02908000);
  CAN0.init_Filt(5, 0, 0x02908000);

  Serial.println("MCP2515 Library Mask & Filter Example...");
  CAN0.setMode(MCP_NORMAL);  // Change to normal mode to allow messages to be transmitted
}

void loop() {
  if (!digitalRead(2))  // If pin 2 is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);  // Read data: len = data length, buf = data byte(s)
    Serial.print("ID: ");
    Serial.print(rxId, HEX);
    Serial.print(" Data: ");
    for (int i = 0; i < len; i++)  // Print each byte of the data
    {
      if (rxBuf[i] < 0x10)  // If data byte is less than 0x10, add a leading zero
      {
        Serial.print("0");
      }
      Serial.print(rxBuf[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
}

/*********************************************************************************************************
END FILE
*********************************************************************************************************/

Moved to Programming Questions.... Please try not to post in Uncategorized again.

start experiments with

uint32_t mymask =      0xFFFFFFFF;  // check all bits
uint32_t myfilter =    0x8CF00400;  //  bits must be set to this


  CAN0.init_Mask(0, 0, mymask);
  CAN0.init_Filt(0, 0, myfilter);
  CAN0.init_Filt(1, 0, myfilter);

  CAN0.init_Mask(1, 0, mymask);
  CAN0.init_Filt(2, 0, myfilter);
  CAN0.init_Filt(3, 0, myfilter);
  CAN0.init_Filt(4, 0, myfilter);
  CAN0.init_Filt(5, 0, myfilter);

Thanks A lot it worked for me

But how my mask is ffffffff please

you said you only want to see exactly one ID. Therefore the full mask has to be activated.

write it down in binary:

0b11111111111111111111111111111111; // the mask
0b10001100111100000000010000000000; // 0x8FC00400

the mask defines which bit positions must be checked --> in your case all
the filter defines how the bit must be set at that position.

ps.: now you can reduce your filters
that should work too

CAN0.init_Mask(0, 0, mymask);
  CAN0.init_Filt(0, 0, myfilter);
  //CAN0.init_Filt(1, 0, myfilter);

  CAN0.init_Mask(1, 0, mymask);
  //CAN0.init_Filt(2, 0, myfilter);
  //CAN0.init_Filt(3, 0, myfilter);
  //CAN0.init_Filt(4, 0, myfilter);
  //CAN0.init_Filt(5, 0, myfilter);

should be

CAN0.init_Mask(0, 0, 0x1FFFFFFF); //for typical 29bit extended CAN ID

in your case, your want to filter for "0x8CF00400" which is 32 bits long. therefore you need to check all the bits as proposed by @noiasca

btw keep the code from post #3. post #6 code will NOT filter correctly!

hope that helps...

Continuing the discussion from CanBus Filtering:

Hi Noiasca The above filters and masks you suggested work, but only for one ID, 0X8CF00400. As soon as I added a second filter to get 0X98FEEE00, it was still the same, giving me 0X8CF00400, but I need both 0X8CF00400 and 0X98FEEE00.

MY FILTERS AND MASKS ARE AS FOLLOWS

The output from this setup is only 0X8CF00400 and is missing 0X98FEEE00.
Can you please suggest a solution?

uint32_t mymask =      0xFFFFFFFF;  // check all bits
uint32_t myfilter =    0x8CF00400;  //  bits must be set to this
uint32_t mymask_1 =      0xFFFFFFFF;  // check all bits
uint32_t myfilter_1 =    0x98FEEE00;  //  bits must be set to this


  CAN0.init_Mask(0, 0, mymask);
  CAN0.init_Filt(0, 0, myfilter);
  CAN0.init_Filt(1, 0, myfilter);

  CAN0.init_Mask(1, 0, mymask_1);
  CAN0.init_Filt(2, 0, myfilter_1);
  CAN0.init_Filt(3, 0, myfilter);
  CAN0.init_Filt(4, 0, myfilter);
  CAN0.init_Filt(5, 0, myfilter);

since u are using extended CAN IDs
CAN0.init_Mask(0, 0, mymask);

should be

CAN0.init_Mask(0, 1, mymask); //as for the 2nd mask as well :wink:

and
CAN0.init_Filt(0, 0, myfilter);

should be
CAN0.init_Filt(0, 1, myfilter); // as for the remaining filters :wink:

'0' disables extended CAN ID filtering and all applied it to standard 11 bits CAN ID

hope that helps....

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