Sketch can bus filter

hi everyone I have recently joined but have been following you for a long time I have an arduino uno and two can bus modules I need a hand I would like to create a sketch to be able to read everything from the network can filter what I need to modify a data and send everything that i receive with the modified data is it possible?

hello forgive me I'm new and so I still don't know how to do it I've tried many sketches and libraries but I can't understand how the filters work if maybe you can help me ?? it is an automotive application, but to simulate everything on the bench I am using an arduino module with two canbus modules one receives the signals in can from the instrument panel the other instead sends them to the bcm speed and 50kbps the filtering must be the following id 1e114003
practically I read 45 00 48 00 01 00 85 00 I should filter the 5 of the first two bytes becoming 0 in this case 40

I can take a picture of you but for now I'm trying to get two Arduino can bus modules to communicate with each other to understand how the filters work

this is only a link to see how the canbus filter works and how I can fix my problem but obviously it was not connected so when I try to connect the instrument panel I use an arduino with two canbus modules I would need a hand with some expert in the sector thanks

For starters you need your two modules to talk to each other. The various can libraries have examples that will do that. Get that working first. Filters as you know are built into the can controller, and the library should allow you to adjust them any way you want. What happens to a lot of first timers they get there transmitter to start sending then it quits, reset it and it does it again. Part of the CAN protocol is an ACK from another module. Without that ACK you will never get it running. You can set one up as a snooper but it will not transmit any data.

1 Like

ok thanks for the help. in fact first I wanted to understand how they work between them and the most logical thing to do and then I will try again with the inserted system. Do you have any library or example to send me? thanks for now

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

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
char msgString[128]; // Array to store serial string

#define CAN0_INT 2 // Set INT to pin 2
MCP_CAN CAN0(10); // Set CS to pin 9

void setup()
{
Serial.begin(9600);

if(CAN0.begin(MCP_ANY, CAN_50KBPS, MCP_8MHZ) == CAN_OK)
Serial.println("MCP2515 Initialized Successfully!");
else
Serial.println("Error Initializing MCP2515...");

CAN0.setMode(MCP_STDEXT);

pinMode(CAN0_INT, INPUT);

CAN0.init_Mask(1,1,0x1FFFFFFF); // Init first mask...
CAN0.init_Filt(1,1,0x1E114000); // Init first filter...

Serial.println("MCP2515 Library Receive Example...");
}

void loop()
{
if(!digitalRead(CAN0_INT)) // If CAN0_INT pin is low, read receive buffer
{
CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)

if((rxId & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
  sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
else
  sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);

Serial.print(msgString);

if((rxId & 0x40000000) == 0x40000000){    // Determine if message is a remote request frame.
  sprintf(msgString, " REMOTE REQUEST FRAME");
  Serial.print(msgString);
} else {
  for(byte i = 0; i<len; i++){
    sprintf(msgString, " 0x%.2X", rxBuf[i]);
    Serial.print(msgString);
  }
}
    
Serial.println();

}
}

for example so it should only read ext id 1E114000 instead it reads everything

hi here I am again with my project that slowly takes shape someone who can help me I am using the libraries of Cory J. Fowler I have fixed almost everything practically I have to read a canbus message modify a data and resend the whole package read with mine modified data.

// 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;
byte rxBuf[8];






MCP_CAN CAN0(10);                          // Set CS to pin 10
MCP_CAN CAN1(9); 

void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  
  if(CAN0.begin(MCP_STDEXT, CAN_50KBPS, MCP_8MHZ) == CAN_OK) Serial.print("MCP2515 Init Okay!!\r\n");
  else Serial.print("MCP2515 Init Failed!!\r\n");
  CAN0.setMode(MCP_NORMAL);
  
  
  CAN0.init_Mask(0,1,0x1FFFFFFF);                // Init first mask...
  CAN0.init_Filt(0,1,0x06214000);                // Init first filter...
  CAN0.init_Filt(1,1,0x06214000);                // Init second filter...
  
  CAN0.init_Mask(1,1,0x1FFFFFFF);                // Init second mask... 
  CAN0.init_Filt(2,1,0x06214000);                // Init third filter...
  CAN0.init_Filt(3,1,0x06214000);                // Init fouth filter...
  CAN0.init_Filt(4,1,0x06214000);                // Init fifth filter...
  CAN0.init_Filt(5,1,0x06214000);                // Init sixth filter...
  
  Serial.println("MCP2515 Library Mask & Filter Example...");

  
  if(CAN1.begin(MCP_STDEXT, CAN_50KBPS, MCP_8MHZ) == CAN_OK) Serial.print("MCP2515 Init Okay!!\r\n");
  else Serial.print("MCP2515 Init Failed!!\r\n");
  CAN1.setMode(MCP_NORMAL);
 
}

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();

      

byte A = 0x40;
byte B = rxBuf[1];
byte C = rxBuf[2];
byte D = rxBuf[3];
byte E = rxBuf[4];
byte F = rxBuf[5];
byte G = rxBuf[6];
byte H = rxBuf[7];
byte data[8] = { A, B, C, D, E, F, G, H };

    CAN0.readMsgBuf(&rxId, &len, rxBuf); 
    
    if(rxBuf[0] == 0x45) 
    
    CAN1.sendMsgBuf(rxId, 1, len, data);

    else

    CAN1.sendMsgBuf(rxId, 1, len, rxBuf);
    
    
   

     
     
      
    
}}

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

So, what are your questions? More specific questions tend to get you better answers.

1 Like

I would like to know if the filter is set well to take into account only id 06214000 second to modify a given form and send it together has all the other data filtered before.

So, does your sketch what you want it to do?

Here are a few things I noted about your code:

Why do you initialize all filters with the same ID? I would just use one filter.

This seems like overly complicated.

byte A = 0x40;
byte B = rxBuf[1];
byte C = rxBuf[2];
byte D = rxBuf[3];
byte E = rxBuf[4];
byte F = rxBuf[5];
byte G = rxBuf[6];
byte H = rxBuf[7];
byte data[8] = { A, B, C, D, E, F, G, H };

If you want it easy, just read it from one array into another. Or use a loop and then modify the element you need changed.

txBuffer[1] = rxBuffer[1];

or in for loop

txBuffer[i] = rxBuffer[i];

If you need comments to describe variables just rename the variables.

CAN0.readMsgBuf(&rxId, &len, rxBuf); // Read data: len = data length, buf = data byte(s)

CAN0.readMsgBuf( &canMessageID, &canMessageDataLength, canRxDataBuffer );

I recommend you review all numbers in your code and make them constants with meaningful names using const or #define.

#define CAN_CONTROLLER_0_CS_PIN 10
const int CAN_CONTROLLER_1_CS_PIN = 9; 

MCP_CAN CAN0( CAN_CONTROLLER_0_CS_PIN );
1 Like

hello friend thanks for the answer and advice I will try to work on it thanks to your tips I need a sketch that can filter id 06214000 read the data of this id modify the first 2 bytes and send together also the data not filtered to the 2 canbus module practically a sketch that is likely to filter canbus data.

Then you should disable the filter. The filter in the CAN controller are there to reduce the workload in the microcontroller. If you need to send all messages to the second CAN bus you will need to read all messages from the first CAN bus and modify the messages you want to modify.

Note: Your system will cause a delay of all CAN messages on the second CAN bus. This may have unintended consequences.

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