autowp / arduino-mcp2515

Arduino MCP2515 CAN interface library
MIT License
787 stars 278 forks source link

Can't get filters to work #10

Open tpitman opened 5 years ago

tpitman commented 5 years ago

I am trying to get filters to work. I have read up on the special handling that the mcp2515 needs. Here is a simple sketch that should filter out ALL can messages that don't have an id of 0x0000 (which should be all).

When I run this on my CAN bus I still get the data that is being sent from other devices. I have tried every combination I can think of.

I have a adafruit huzzah32 which uses the esp32. I also have this CAN featherboard:

https://easyeda.com/armin.von_collrepp/Adafruit_CAN_FeatherWing-0YRL3lfxP

The CAN board works fine as I am getting the CAN traffic. I just can get it to filter correctly.

Can someone please tell me why filters don't seem to be working?

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg;
MCP2515 mcp2515(A5);

void setup()
{
  Serial.begin(115200);
  SPI.begin();

  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS);
  mcp2515.setConfigMode();
  mcp2515.setFilterMask(MCP2515::MASK0, false, 0x07FF0000);
  mcp2515.setFilter(MCP2515::RXF0, false, 0x00000000);
  mcp2515.setFilter(MCP2515::RXF1, false, 0x00000000);
  mcp2515.setFilterMask(MCP2515::MASK1, false, 0x07FF0000);
  mcp2515.setFilter(MCP2515::RXF2, false, 0x00000000);
  mcp2515.setFilter(MCP2515::RXF3, false, 0x00000000);
  mcp2515.setFilter(MCP2515::RXF4, false, 0x00000000);
  mcp2515.setFilter(MCP2515::RXF5, false, 0x00000000);
  mcp2515.setNormalMode();

  Serial.println("------- CAN Read ----------");
  Serial.println("ID  DLC   DATA");
}

void loop()
{
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK)
  {
    Serial.print(canMsg.can_id, HEX); // print ID
    Serial.print(" "); 
    Serial.print(canMsg.can_dlc, HEX); // print DLC
    Serial.print(" ");

    for (int i = 0; i<canMsg.can_dlc; i++) 
    {
      Serial.print(canMsg.data[i],HEX);
      Serial.print(" ");
    }

    Serial.println();
  }

  delay(10);
}
autowp commented 5 years ago

Zero in mask means "bit value not matters, accept any".

So, 0x07FF0000 means accept any message with any value in id (for 11bit ID)

Use FF...FF mask to filter out all except one (id=0 in your example)

tpitman commented 5 years ago

I tried all 0xFFFFFFFF and that didn't help.

I also read many postings about the 2515 specifically and they say that it works a little weird with its filters in that the top 2 bytes are used for the filter, but the lower 2 bytes are used to filter the first 2 bytes of data.

Therefore according to this I must have the lower 2 bytes be 00 00 if I don't want to filter the data at all.

The example I gave is exactly what I read I should have and saw in many examples on the 2515.

Please advise if the information I have is wrong.

tpitman commented 5 years ago

Let me ask another way so that we can clarify.

If I only want to allow CAN messages for 7EC what would be my mask and pattern for that?

I want to allow all data, but only 7EC as the CANID.

MalteBahr commented 5 years ago

I might be wrong, but I think I just got it to work (with 11 bit identifiers). The "false" flag specifies that you don't use the extended format, and therefore only need to give an 11 bit mask/filter. I needed only the messages by id=0x613, my code is as follows and seems to work:

  mcp2515.setConfigMode();
  mcp2515.setFilterMask(MCP2515::MASK0, false, 0x7FF);
  mcp2515.setFilter(MCP2515::RXF0, false, 0x613);
  mcp2515.setFilter(MCP2515::RXF1, false, 0x613);
  mcp2515.setFilterMask(MCP2515::MASK1, false, 0x7FF);
  mcp2515.setFilter(MCP2515::RXF2, false, 0x613);
  mcp2515.setFilter(MCP2515::RXF3, false, 0x613);
  mcp2515.setFilter(MCP2515::RXF4, false, 0x613);
  mcp2515.setFilter(MCP2515::RXF5, false, 0x613);
  mcp2515.setNormalMode();
Davi512 commented 2 years ago

Ok what about when I need to filter two ID,s?

kolabse commented 2 years ago

Ok what about when I need to filter two ID,s?

Set different IDs in different filters

    mcp2515.setConfigMode();
    mcp2515.setFilterMask(MCP2515::MASK0, false, 0x7FF);
    mcp2515.setFilterMask(MCP2515::MASK1, false, 0x7FF);

    mcp2515.setFilter(MCP2515::RXF0, false, 0x036);
    mcp2515.setFilter(MCP2515::RXF1, false, 0x0B6);
    mcp2515.setFilter(MCP2515::RXF2, false, 0x0E6);
    mcp2515.setFilter(MCP2515::RXF3, false, 0x0F6);
    mcp2515.setFilter(MCP2515::RXF4, false, 0x1D0);
    mcp2515.setFilter(MCP2515::RXF5, false, 0x221);
    mcp2515.setNormalMode();
Davi512 commented 2 years ago

I need data from 0x308 and 0x608. When I set like this, I recive once 608 then only 308... What I do wrong?

` mcp2515.setConfigMode(); mcp2515.setFilterMask(MCP2515::MASK0, false, 0x7FF); mcp2515.setFilterMask(MCP2515::MASK1, false, 0x7FF);

mcp2515.setFilter(MCP2515::RXF0, false, 0x308);
mcp2515.setFilter(MCP2515::RXF1, false, 0x608);
mcp2515.setFilter(MCP2515::RXF2, false, 0x608);
mcp2515.setFilter(MCP2515::RXF3, false, 0x608);
mcp2515.setFilter(MCP2515::RXF4, false, 0x608);
mcp2515.setFilter(MCP2515::RXF5, false, 0x608);
mcp2515.setNormalMode();`
Davi512 commented 2 years ago

I use this and can filter only one id, I dont know what is wrong when I type 0x308 I recieve 308 only. I need 608 and 308 mcp2515.setConfigMode(); mcp2515.setFilterMask(MCP2515::MASK0, false, 0x03FF); mcp2515.setFilterMask(MCP2515::MASK1, false, 0x03FF);

mcp2515.setFilter(MCP2515::RXF0, false, 0x608); mcp2515.setFilter(MCP2515::RXF1, false, 0x608); mcp2515.setFilter(MCP2515::RXF2, false, 0x608); mcp2515.setFilter(MCP2515::RXF3, false, 0x608); mcp2515.setFilter(MCP2515::RXF4, false, 0x608); mcp2515.setFilter(MCP2515::RXF5, false, 0x608);

Davi512 commented 2 years ago

Any one can help?

rikysuhendra commented 1 year ago

Hi, you may write like code bellow

mcp2515.reset(); mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ); //mcp2515.setConfigMode(); //<< do not use this mcp2515.setFilterMask(MCP2515::MASK0, false, 0x7ff); mcp2515.setFilter(MCP2515::RXF0, false, 0x308); mcp2515.setFilter(MCP2515::RXF1, false, 0x608); mcp2515.setFilterMask(MCP2515::MASK1, false, 0x7ff); mcp2515.setFilter(MCP2515::RXF0, false, 0x308); mcp2515.setFilter(MCP2515::RXF1, false, 0x608); mcp2515.setNormalMode();

its work for me, mcp2515 only receive data with 0x308 and 0x608 address