Issue with Can Bus Filter ID's
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.
What happens when you Software Filter it? like:
if ((CAN.packetId() == 0x18daf110) {
while (CAN.available()) { Serial.print((char)CAN.read(), HEX); }
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 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
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
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!
also may consider this comit: https://github.com/sandeepmistry/arduino-CAN/pull/27
for direct access of the Raw Can buffer.
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];
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];
}
}
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 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.
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,
Fixed by #117.