I have read most if not all of the CANBUS filtering posts but I'm still struggling to get it to work,
I'm trying to filter on ID 0x18A, as per my understanding, it allows only mentioned CAN ID and blocks the rest. I applied it in code, but it works the opposite. it blocks the mentioned ID and allowing rest.
Full code at the bottom of post.
Someone can help me out?
Regards,
#include <SPI.h>
#include <mcp_can.h>
#define CS_PIN 5 // Chip select pin for the MCP2515
MCP_CAN CAN(CS_PIN); // Set CS pin
char msgString[128];
void setup() {
Serial.begin(115200);
if (CAN.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK) // Initialize MCP2515 with 500kbps and 8MHz clock
{
Serial.println("MCP2515 Initialized Successfully!");
} else {
Serial.println("Error Initializing MCP2515...");
while (1);
}
// Set the mask to apply to all bits (standard CAN IDs are 11 bits long)
CAN.init_Mask(0, 0, 0x7FF); // Mask 0
CAN.init_Mask(1, 0, 0x7FF); // Mask 1
// Set the filter to match the CAN ID 0x18A
CAN.init_Filt(0, 0, 0x18A); // Filter 0
CAN.setMode(MCP_NORMAL); // Set MCP2515 to normal mode
}
void loop() {
unsigned char len = 0;
unsigned char rxbuf[8];
unsigned long rxId;
if (CAN_MSGAVAIL == CAN.checkReceive()) // Check if data is available
{
CAN.readMsgBuf(&rxId, &len, rxbuf); // Read data: len is data length, buf is data byte(s)
Serial.print("Received CAN ID: ");
Serial.print(rxId, HEX);
Serial.print(" DLC: ");
Serial.print(len);
Serial.print(" Data: ");
for (int i = 0; i < len; i++) // Print each byte of the data
{
if (rxbuf[i] < 0x10)
{
Serial.print("0"); // Add leading zero for single digit hex values
}
Serial.print(rxbuf[i], HEX);
Serial.print(" ");
}
Serial.println();
}
}
#include <SPI.h>
#include <mcp_can.h>
#define CS_PIN 5 // Chip select pin for the MCP2515
MCP_CAN CAN(CS_PIN); // Set CS pin
char msgString[128];
void setup() {
Serial.begin(115200);
// Initialize MCP2515 with 500kbps and 8MHz clock
if (CAN.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK)Serial.println("MCP2515 Initialized Successfully!");
else {
Serial.println("Error Initializing MCP2515...");
while (1);
}
// Set the mask to apply to all bits (standard CAN IDs are 11 bits long)
CAN.init_Mask(0, 0, 0x7FF); // Mask 0
CAN.init_Mask(1, 0, 0x7FF); // Mask 1
CAN.setMode(MCP_NORMAL); // Set MCP2515 to normal mode
}
void loop() {
unsigned char len = 0;
unsigned char rxbuf[8];
unsigned long rxId;
if (CAN_MSGAVAIL == CAN.checkReceive()) { // Check if data is available
CAN.readMsgBuf(&rxId, &len, rxbuf); // Read data: len is data length, buf is data byte(s)
if (0x18A == rxId) {
Serial.print("Received CAN ID: ");
Serial.print(rxId, HEX);
Serial.print(" DLC: ");
Serial.print(len);
Serial.print(" Data: ");
for (int i = 0; i < len; i++) { // Print each byte of the data
if (rxbuf[i] < 0x10)Serial.print("0"); // Add leading zero for single digit hex values
Serial.print(rxbuf[i], HEX);
Serial.print(" ");
}
Serial.println();
}
}
}
definetely most!
coz if you did read all, you would have know that you need to set ALL the filters, not just the one!
ie
-// Set the filter to match the CAN ID 0x18A
CAN.init_Filt(0,0,0x018A0000); // Init first filter...
CAN.init_Filt(1,0,0x018A0000); // Init second filter..
CAN.init_Filt(2,0,0x018A0000); // Init third filter...
CAN.init_Filt(3,0,0x018A0000); // Init fourth filter...
CAN.init_Filt(4,0,0x018A0000); // Init fifth filter...
CAN.init_Filt(5,0,0x018A0000); // Init sixth filter...
hope that helps....
My product transmit 100 message per second its a huge, used Mega but its freezing after 10 min. so now moved to ESP32 and need this filter.
if i use if (0x18A == rxId) this condition still ill get all the messages. it will not reduce load on MCU.
@sherzaad yes and in most of the posts you have present ,
i have checked all solution that you have posted in other posts.
your logic is worked but opposite, I need 0x18A on output but it blocking that id.
also one dough ! should i need to add 0000 after ID.
do you mean CAN module make filtering alone? by self?
yes
one other thing I missed, is that in your code you shared, you are setting the masks incorrectly (why are you not following the way it was written in the library example!)
so, the masks should be written as follows:
CAN.init_Mask(0,0,0x07FF0000); // Init first mask...
CAN.init_Mask(1,0,0x07FF0000); // Init second mask...
so combined with post#3 you would be only have 0x18A can frame output
CAN.init_Mask(0,0,0x07FF0000); // Init first mask...
CAN.init_Filt(0,0,0x018A0000); // Init first filter...
CAN.init_Filt(1,0,0x018A0000); // Init second filter..
CAN.init_Mask(1,0,0x07FF0000); // Init second mask...
CAN.init_Filt(2,0,0x018A0000); // Init third filter...
CAN.init_Filt(3,0,0x018A0000); // Init fourth filter...
CAN.init_Filt(4,0,0x018A0000); // Init fifth filter...
CAN.init_Filt(5,0,0x018A0000); // Init sixth filter...
good luck!
2 Likes
YES ! MCP2515 has filter and Mask option.
Ill try this and let you know.
Thanks brother !
Ahhh Haaaa...!!! Finally it works, i have wasted week on this.. Thanks a lot @sherzaad,
One more thing, previously I was using Arduino Mega and controlling some relays depending on CAN ID's, in that Arduino Mega Freeze after 10mins. My product has aground 93 messages each message appears 100 times each second so it will be nearby 9300 messages per second. its huge CAN messages for Mega.
That's why i moved to ESP32-D, and this Filter and Mask option.
I have some Question ...!!
- Will it reduce the Load on MCU ?
- In this filter MCP2515 will block the message or MCU.?
the filter is set on the MCP2515 ie MCP2515 will only pass 0x18A frame to MCU
depends what ur doing on the MCU
but for sure the MCU will have less CAN messages to process with the MCP2515 filter set which will take a load off the MCU