arduino-CAN icon indicating copy to clipboard operation
arduino-CAN copied to clipboard

Issue with Can Bus Filter ID's

Open Nikhil0351 opened this issue 5 years ago • 10 comments

Thanks, Sandeep Mistry for the Library!

I need a little help with my Code. I am working with an ESP32 and a TCAN334. We are facing issue with Filtering Ids. we are using the sample code provided with the library. Without filter we are getting the data over can bus. But when we apply filters we did not receive any data. we checked with the library, and ACR registers are correctly set.

We are trying filter with 0x18daf110 (Honda Jazz)


#include <CAN.h>

const bool useStandardAddressing = false;


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

  Serial.println("CAN Receiver");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }


  if (useStandardAddressing) {
    CAN.filter(0x7E8);
  } else {

    CAN.filterExtended(0x18daf110  );

  }
}

void loop() {

  if (useStandardAddressing) {
    CAN.beginPacket(0x7DF, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }

  int packetSize = CAN.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Received ");

    if (CAN.packetExtended()) {
      Serial.print("extended ");
    }

    if (CAN.packetRtr()) {
      // Remote transmission request, packet contains no data
      Serial.print("RTR ");
    }
    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);
    if (CAN.packetRtr()) {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    } else {
      Serial.print(" and length ");
      Serial.println(packetSize);
      // only print packet data for non-RTR packets
      while (CAN.available()) {
        Serial.print((char)CAN.read(), HEX);
      }
      Serial.println();
    }
    Serial.println();

  }

maybe someone can help me out.

Nikhil0351 avatar Jan 22 '20 12:01 Nikhil0351

What happens when you Software Filter it? like:

if ((CAN.packetId() == 0x18daf110) {

while (CAN.available()) { Serial.print((char)CAN.read(), HEX); }

Petros144 avatar Mar 17 '20 11:03 Petros144

thank you with your lib I have a problem with mask and filtering I wanna receive one of the id's in can bus Sensor_ID_in_DEC = (CAN.packetId()); CAN.filter(Sensor_ID_in_DEC, Sensor_ID_in_DEC); is it the right thing to do of course not cuz it's not working (is there any example to just receive a specific id ) or anyone can help me with this ill appreciate it thankyou

mehrdad987 avatar Apr 25 '20 14:04 mehrdad987

@mehrdad987 You read the bus and save the Vaiable to then filter it? - this not the right way. "Sensor_ID_in_DEC = (CAN.packetId());"


Filter like this:

CAN.filter(0x7E8);

You will ONLY recive the given ID, in this case 0x7E8.

This is how it works. if you want multiple or a Range you need to make it in software like in my post above

Petros144 avatar Apr 25 '20 21:04 Petros144

yep but it's not working I have many ids in can bus and I wanna receive one of them and if I USE CAN.filter(0xCFF001); it ll receive nothing and also it's not good cuz its find the id randomly

mehrdad987 avatar Apr 26 '20 07:04 mehrdad987

dont use the can.avalable it is too slow.

also do this in the reciver callback. it is mutch faster and filters all ids that you want!

Petros144 avatar Apr 26 '20 12:04 Petros144

also may consider this comit: https://github.com/sandeepmistry/arduino-CAN/pull/27

for direct access of the Raw Can buffer.

Petros144 avatar Apr 26 '20 12:04 Petros144

YOU MEAN THIS virtual void onReceive(void(*callback)(int)); actually I'm a beginner and I don't know how to use it if it's possible to make an example<>ill appreciate it

packetSize = CAN.parsePacket();
if (packetSize) {
  if (CAN.packetExtended()) {
  }
  if (CAN.packetRtr()) {
  }
  if((CAN.packetId())== 218038273){
    while (CAN.available()) {
      byte buff[8];
      CAN.readBytes((char *)buff,8);
      unsigned int byte0 = buff[0];

mehrdad987 avatar Apr 27 '20 06:04 mehrdad987

Try this:

But user the Lib for Raw buffer access:

https://github.com/sandeepmistry/arduino-CAN/pull/27

//Globals

#include <CAN.h> uint8_t CanB[8];

int byte1; int byte2; int byte3; int byte4; int byte5; int byte6; int byte7; int byte8;

void setup() {

CAN.begin(500E3); //Baud Rate CAN.onReceive(onReceive); //Calback

}

void loop() { //Print packet Serial.println(byte1); Serial.println(byte2); Serial.println(byte3); Serial.println(byte4); Serial.println(byte5); Serial.println(byte6); Serial.println(byte7); Serial.println(byte8);

}

void onReceive(int packetSize) {

CAN.readBytes(CanB, 8); // CanB is the Name of the Buffer

if (CAN.packetId() == 0x220) {

byte1 = CanB[0];
byte2 = CanB[1];
byte3 = CanB[2];
byte4 = CanB[3];
byte5 = CanB[4];
byte6 = CanB[5];
byte7 = CanB[6];
byte8 = CanB[7];

}

}

Petros144 avatar Apr 27 '20 19:04 Petros144

Hi, I'm a newbie in programming and Arduino, sorry for the dumb questions below! :

Taking a look at the last code, I see that CAN.onReceive(onReceive) is a replacement to CAN.parsePacket() and CAN.available to receive CAN packets in order to get good filtering capabilities. But CAN.onReceive is only executed once because it's in the void setup() function. Does this mean that only one packet will be captured during program execution? If not, how is it possible that void onReceive(int packetSize) is called multiple times if it's not called out from the void loop () function?

Also, If I'd like to filter the data buffer (ID=0x206, byte1=01 byte2=84 byte3=00 byte4,5,6,7,8=00), would it be fine if I used an IF statement inside the void loop()...or should it be inside the void onReceive(int packetSize) function? For instance, what I'd do is:

void(loop){

   if(byte1==0x01 && byte2==0x84 && byte3==0x00){
   // actions here (send media commands over bluetooth)

}

Thanks in advance

zalexzperez avatar Mar 18 '21 21:03 zalexzperez

@zalexzperez CAN.onReceive(xyz) sets up xyz as a callback. It should be called for every message received.

If you want to filter packets by data, you probably want to do it in the callback function, not the loop() function.

timurrrr avatar Mar 19 '21 06:03 timurrrr

I encountered a problem where ESP32 would freeze when using extended ID for communication. The freeze usually happened after 5 to 40 minutes, and it was difficult to identify the cause. Therefore, I attempted to implement filtering by ID to improve stability, but I got a runtime error. Thus, I made the modifications according to #117 , which fixed the freezing issue simultaneously. I believe that the PR of #117 will be the solution to this issue. Bests,

kouuta avatar Mar 08 '23 14:03 kouuta

Fixed by #117.

sandeepmistry avatar Mar 09 '23 02:03 sandeepmistry