FlexCAN_T4 - FlexCAN for Teensy 4

you mean like 33,333 and 10? it works but all nodes must match

Sorry, I had tried the following (as I'm attempting to connect to existing automotive CAN system at some point, which is 33,333 with a tolerance of 0.35% or 33,217 - 33,449)

Code:
    Can0.setBaudRate(33333);

When I set this, the CANTX pin never changed, nothing gets transmitted on the bus. All these tested: 33,300, 33,333, 33,334, & 33,500.

What did work was 40,000 & 32,000 (CANTX has waveform and packets are received by 2nd Teensy).

So without exhaustively testing all baud rates, I could run the T4 ARM clock at 625MHz & baud at 32000 or T4 @ 495MHz & baud at 40000.

Is this the way?
 
Last edited:
did you try changing the clock? all teensy flexcan libraries (can2.0) use the same calculation script, try it with different clocks (setClock()) and try your baudrates with the new clock.

teensy 3.x clock was 16MHz, T4 is switchable with setClock(), default on T4 is 24MHz

im not talking about your cpu speed, flexcan has it's own clock :)
 
Teensy4.0 + MCP2562 29bit Extended CANID OBD communication

I'm trying to talk with Honda fit via OBD protocol using Teensy4.0 + MCP2562.
I can talk with the vehicles which is using standard CAN such as 7E0, 7E8 type.
But I cannot send request messages and receive response messages from ECU, too.
So far I checked the CAN communication between GST and ECU by Vehicle Spy (Intrepid Control Systems) and I'm using the same extended CANID for Teensy4.0.

Is there something worng with my code change or still more work to do for extended CANID?

Here's an example Vehicle Spy CAN Monitor screen using Generic Scantool.

Honda_CAN_comm.gif


Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

int engineCoolantTemp = 0; // Save the data here

void setup(){
  while (!Serial && millis() < 5000);
  Serial.begin(115200);
  Can0.begin();
  Can0.setBaudRate(500000);
  Can0.setMBFilter(REJECT_ALL);
 // Can0.setMBFilter(MB1, 0x7E8); // Standard CANID  ENG ECU -> TESTER
  Can0.setMBFilter(MB1, 0x18DAF111); // Extended CANID  ENG ECU -> TESTER (Physical Addressing)
  Can0.enableMBInterrupt(MB1);
  Can0.onReceive(canSniff);

}

const long loopDelay1 = 500; // Make a request every 500ms
unsigned long timeNow1 = 0;
void loop(){
  Can0.events();
  if (millis() > timeNow1 + loopDelay1)
    {
      timeNow1 = millis();
      canTx_OBD(); // Query data from CAN BUS via OBD
      //canTx_UDS(); // Query data from CAN BUS via UDS

    }
}


void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in
  Serial.println(" ");
  Serial.print("MB: ");
  Serial.print(msg.mb);
  Serial.print("  ID: 0x");
  Serial.print(msg.id, HEX);
  Serial.print("  EXT: ");
  Serial.print(msg.flags.extended);
  Serial.print("  LEN: ");
  Serial.print(msg.len);
  Serial.print(" DATA: ");
  for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(msg.buf[i], HEX);
      Serial.print(" ");
    }
    if (msg.buf[1] == 0x01 && msg.buf[2] == 0x05){     // SID$01 PID$05 Engine Coolant Temperature
        engineCoolantTemp = msg.buf[3] - 40;           // Offset -40(degC)
        Serial.println(" ");
        Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

    if (msg.buf[1] == 0x22 && msg.buf[2] == 0xf4 && msg.buf[3] == 0x05){     // Checking positive reponse
        engineCoolantTemp = msg.buf[4] - 40;
        Serial.println(" ");
        Serial.printf("UDS: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

}


void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x02;     // Data Length 2byte
    msgTx.buf[1] = 0x01;     // Service$01
    msgTx.buf[2] = 0x05;     // PID $05 Engine Coolant Temperature
    msgTx.buf[3] = 0;        // Padding
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0;
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit 
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit 
    msgTx.flags.remote = 0;
    
    //msgTx.id = 0x7E0; // request header for OBD           // Physical Addressing Request to Engine ECU
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    Can0.write(msgTx);
    Serial.println("canTx_OBD REQ sent"); 
  }

 void canTx_UDS(){ // Request function to ask for Engine Coolant Temp via UDS request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x03;      // Data Length
    msgTx.buf[1] = 0x22;      // SID$22 Request parameter by Data Identifier
    msgTx.buf[2] = 0xf4;      // 
    msgTx.buf[3] = 0x05;      // PID$05 is Engine Coolant Temperature
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0; 
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit
    
    msgTx.flags.remote = 0;
    //msgTx.id = 0x7E0; // request header for OBD
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    Can0.write(msgTx); 
    Serial.println("canTx_UDS REQ sent"); 
  }
 
Last edited:
I'm trying to talk with Honda fit via OBD protocol using Teensy4.0 + MCP2562.
I can talk with the vehicles which is using standard CAN such as 7E0, 7E8 type.
But I cannot send request messages and receive response messages from ECU, too.
So far I checked the CAN communication between GST and ECU by Vehicle Spy (Intrepid Control Systems) and I'm using the same extended CANID for Teensy4.0.

Is there something worng with my code change or still more work to do for extended CANID?

Here's an example Vehicle Spy CAN Monitor screen using Generic Scantool.

View attachment 23328


Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

int engineCoolantTemp = 0; // Save the data here

void setup(){
  while (!Serial && millis() < 5000);
  Serial.begin(115200);
  Can0.begin();
  Can0.setBaudRate(500000);
  Can0.setMBFilter(REJECT_ALL);
 // Can0.setMBFilter(MB1, 0x7E8); // Standard CANID  ENG ECU -> TESTER
  Can0.setMBFilter(MB1, 0x18DAF111); // Extended CANID  ENG ECU -> TESTER (Physical Addressing)
  Can0.enableMBInterrupt(MB1);
  Can0.onReceive(canSniff);

}

const long loopDelay1 = 500; // Make a request every 500ms
unsigned long timeNow1 = 0;
void loop(){
  Can0.events();
  if (millis() > timeNow1 + loopDelay1)
    {
      timeNow1 = millis();
      canTx_OBD(); // Query data from CAN BUS via OBD
      //canTx_UDS(); // Query data from CAN BUS via UDS

    }
}


void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in
  Serial.println(" ");
  Serial.print("MB: ");
  Serial.print(msg.mb);
  Serial.print("  ID: 0x");
  Serial.print(msg.id, HEX);
  Serial.print("  EXT: ");
  Serial.print(msg.flags.extended);
  Serial.print("  LEN: ");
  Serial.print(msg.len);
  Serial.print(" DATA: ");
  for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(msg.buf[i], HEX);
      Serial.print(" ");
    }
    if (msg.buf[1] == 0x01 && msg.buf[2] == 0x05){     // SID$01 PID$05 Engine Coolant Temperature
        engineCoolantTemp = msg.buf[3] - 40;           // Offset -40(degC)
        Serial.println(" ");
        Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

    if (msg.buf[1] == 0x22 && msg.buf[2] == 0xf4 && msg.buf[3] == 0x05){     // Checking positive reponse
        engineCoolantTemp = msg.buf[4] - 40;
        Serial.println(" ");
        Serial.printf("UDS: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

}


void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x02;     // Data Length 2byte
    msgTx.buf[1] = 0x01;     // Service$01
    msgTx.buf[2] = 0x05;     // PID $05 Engine Coolant Temperature
    msgTx.buf[3] = 0;        // Padding
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0;
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit 
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit 
    msgTx.flags.remote = 0;
    
    //msgTx.id = 0x7E0; // request header for OBD           // Physical Addressing Request to Engine ECU
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    Can0.write(msgTx);
    Serial.println("canTx_OBD REQ sent"); 
  }

 void canTx_UDS(){ // Request function to ask for Engine Coolant Temp via UDS request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x03;      // Data Length
    msgTx.buf[1] = 0x22;      // SID$22 Request parameter by Data Identifier
    msgTx.buf[2] = 0xf4;      // 
    msgTx.buf[3] = 0x05;      // PID$05 is Engine Coolant Temperature
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0; 
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit
    
    msgTx.flags.remote = 0;
    //msgTx.id = 0x7E0; // request header for OBD
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    Can0.write(msgTx); 
    Serial.println("canTx_UDS REQ sent"); 
  }

Positive response will be 0x41 for Mode 01 and 0x62 for mode 22
That’s probably why you’re not going into any of the if conditions in your rx callback
 
I'm trying to talk with Honda fit via OBD protocol using Teensy4.0 + MCP2562.
I can talk with the vehicles which is using standard CAN such as 7E0, 7E8 type.
But I cannot send request messages and receive response messages from ECU, too.
So far I checked the CAN communication between GST and ECU by Vehicle Spy (Intrepid Control Systems) and I'm using the same extended CANID for Teensy4.0.

Is there something worng with my code change or still more work to do for extended CANID?

Here's an example Vehicle Spy CAN Monitor screen using Generic Scantool.

View attachment 23328


Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

int engineCoolantTemp = 0; // Save the data here

void setup(){
  while (!Serial && millis() < 5000);
  Serial.begin(115200);
  Can0.begin();
  Can0.setBaudRate(500000);
  Can0.setMBFilter(REJECT_ALL);
 // Can0.setMBFilter(MB1, 0x7E8); // Standard CANID  ENG ECU -> TESTER
  Can0.setMBFilter(MB1, 0x18DAF111); // Extended CANID  ENG ECU -> TESTER (Physical Addressing)
  Can0.enableMBInterrupt(MB1);
  Can0.onReceive(canSniff);

}

const long loopDelay1 = 500; // Make a request every 500ms
unsigned long timeNow1 = 0;
void loop(){
  Can0.events();
  if (millis() > timeNow1 + loopDelay1)
    {
      timeNow1 = millis();
      canTx_OBD(); // Query data from CAN BUS via OBD
      //canTx_UDS(); // Query data from CAN BUS via UDS

    }
}


void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in
  Serial.println(" ");
  Serial.print("MB: ");
  Serial.print(msg.mb);
  Serial.print("  ID: 0x");
  Serial.print(msg.id, HEX);
  Serial.print("  EXT: ");
  Serial.print(msg.flags.extended);
  Serial.print("  LEN: ");
  Serial.print(msg.len);
  Serial.print(" DATA: ");
  for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(msg.buf[i], HEX);
      Serial.print(" ");
    }
    if (msg.buf[1] == 0x01 && msg.buf[2] == 0x05){     // SID$01 PID$05 Engine Coolant Temperature
        engineCoolantTemp = msg.buf[3] - 40;           // Offset -40(degC)
        Serial.println(" ");
        Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

    if (msg.buf[1] == 0x22 && msg.buf[2] == 0xf4 && msg.buf[3] == 0x05){     // Checking positive reponse
        engineCoolantTemp = msg.buf[4] - 40;
        Serial.println(" ");
        Serial.printf("UDS: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

}


void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x02;     // Data Length 2byte
    msgTx.buf[1] = 0x01;     // Service$01
    msgTx.buf[2] = 0x05;     // PID $05 Engine Coolant Temperature
    msgTx.buf[3] = 0;        // Padding
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0;
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit 
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit 
    msgTx.flags.remote = 0;
    
    //msgTx.id = 0x7E0; // request header for OBD           // Physical Addressing Request to Engine ECU
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    Can0.write(msgTx);
    Serial.println("canTx_OBD REQ sent"); 
  }

 void canTx_UDS(){ // Request function to ask for Engine Coolant Temp via UDS request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x03;      // Data Length
    msgTx.buf[1] = 0x22;      // SID$22 Request parameter by Data Identifier
    msgTx.buf[2] = 0xf4;      // 
    msgTx.buf[3] = 0x05;      // PID$05 is Engine Coolant Temperature
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0; 
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit
    
    msgTx.flags.remote = 0;
    //msgTx.id = 0x7E0; // request header for OBD
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    Can0.write(msgTx); 
    Serial.println("canTx_UDS REQ sent"); 
  }

Teensyduino doesn't include the latest FlexCAN_T4 library, so make sure you get it from here: https://github.com/tonton81/FlexCAN_T4
When enableInterrupts is set in setup, events() should be removed from the loop.
 
Thank you, Rezo.

My source code handling positive response was wrong.
I corrected positive response as you mentioned. 0x41 for mode$01 (service$01), and 0x62 for mode22.
However any response message from ECU cannot be received.

For checking CAN connection, I tried "read_two_channels.ino" and I can read normal can communication.
 
remove the condition checks to make sure you see the frame first, usually print it out, easier to debug. also remove filtering until you get the expected output, then you may filter frames as needed

also just so you know, MB1 is a standard mailbox, so don't expect to filter an extended frame :) you are not using FIFO so try to use MB4-7 for filtering as they are extended mailboxes. To view the layout, use mailboxStatus(), you can reconfigure mailboxes however you like, but pay attention to defaults
 
Thank you msadie,
I have updated the FlexCAN_T4 library with the latest one, and removed events() from the code.
But the symptom is the same.
I have updated the source code with the latest one.
The exact can port I am using is can2, not can0 due to wiring convenience.
For standard CAN, there was no problem. But should I change can port from can2 to can0?

Teensy4_mcp2562.jpg

Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;

int engineCoolantTemp = 0; // Save the data here

void setup(){
  while (!Serial && millis() < 5000);
  Serial.begin(115200);
  can2.begin();
  can2.setBaudRate(500000);
  can2.setMBFilter(REJECT_ALL);
 // can2.setMBFilter(MB1, 0x7E8); // Standard CANID  ENG ECU -> TESTER
  can2.setMBFilter(MB1, 0x18DAF111, EXT); // Extended CANID  ENG ECU -> TESTER (Physical Addressing)
  can2.enableMBInterrupt(MB1);
  can2.onReceive(canSniff);

}

const long loopDelay1 = 500; // Make a request every 500ms
unsigned long timeNow1 = 0;
void loop(){
  //can2.events();
  if (millis() > timeNow1 + loopDelay1)
    {
      timeNow1 = millis();
      canTx_OBD(); // Query data from CAN BUS via OBD
      //canTx_UDS(); // Query data from CAN BUS via UDS

    }
}


void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in
  Serial.println(" ");
  Serial.print("MB: ");
  Serial.print(msg.mb);
  Serial.print("  ID: 0x");
  Serial.print(msg.id, HEX);
  Serial.print("  EXT: ");
  Serial.print(msg.flags.extended);
  Serial.print("  LEN: ");
  Serial.print(msg.len);
  Serial.print(" DATA: ");
  for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(msg.buf[i], HEX);
      Serial.print(" ");
    }
    if (msg.buf[1] == 0x41 && msg.buf[2] == 0x05){     // SID$01 PID$05 Engine Coolant Temperature
        engineCoolantTemp = msg.buf[3] - 40;           // Offset -40(degC)
        Serial.println(" ");
        Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

    if (msg.buf[1] == 0x62 && msg.buf[2] == 0xf4 && msg.buf[3] == 0x05){     // Checking positive reponse
        engineCoolantTemp = msg.buf[4] - 40;
        Serial.println(" ");
        Serial.printf("UDS: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

}


void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x02;     // Data Length 2byte
    msgTx.buf[1] = 0x01;     // Service$01
    msgTx.buf[2] = 0x05;     // PID $05 Engine Coolant Temperature
    msgTx.buf[3] = 0x55;        // Padding
    msgTx.buf[4] = 0x55;
    msgTx.buf[5] = 0x55; 
    msgTx.buf[6] = 0x55;
    msgTx.buf[7] = 0x55;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit 
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit 
    msgTx.flags.remote = 0;
    
    //msgTx.id = 0x7E0; // request header for OBD           // Physical Addressing Request to Engine ECU
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    can2.write(msgTx);
    Serial.println("canTx_OBD REQ sent"); 
  }

 void canTx_UDS(){ // Request function to ask for Engine Coolant Temp via UDS request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x03;      // Data Length
    msgTx.buf[1] = 0x22;      // SID$22 Request parameter by Data Identifier
    msgTx.buf[2] = 0xf4;      // 
    msgTx.buf[3] = 0x05;      // PID$05 is Engine Coolant Temperature
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0; 
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit
    
    msgTx.flags.remote = 0;
    //msgTx.id = 0x7E0; // request header for OBD
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    can2.write(msgTx); 
    Serial.println("canTx_UDS REQ sent"); 
  }
 
read my post above
EXT is used for setMB(), optional parameters in setMBFilter are for multiple IDs only

mailboxStatus() will display MB1 as a STD mailbox. use MB4 for extended receptions.
 
Thank you, tonton81,

I didn't know the Mail Box difference. It is a big help. I will try MB4 - MB7.
Also thanks for debugging advices.
 
Thank you, tonton81,

I didn't know the Mail Box difference. It is a big help. I will try MB4 - MB7.
Also thanks for debugging advices.

Did you take your UDS example from a Hackster article? If so it might be mine.

I'm not sure 0xF405 will yield anything unless it's being requested from a VW/Audi MQB platform vehicle (that's what I tested on)
My best suggestions is to get a UDS based data logger or diagnostics tool and see if it can display sensor values - if you can find something like that, use a Y splitter and sniff the device while it's connected to the car.
 
My vehicle does not support UDS. So, UDS part of the source code cannot be tested and therefore I'm not sure whether it works or not.
Anyway I will debug ISO-15765-4 part (mode$01 or Service$01 CAN) with extended CANID.

When it works, I want to try multi-frame protocol (ISO-1765-2), which is necessary for Mode$03/$07/$09 requests.
 
TEENSY 4.1 CAN bus question about speed?

The CAN bus is working perfectly except it seems to only update every 0.5 seconds and I dont know why :( You can see in the code that I have the BaudRate set to 1000000 so I don't know why its updating so slow.

Maybe something is wrong with my setup code?

#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

Can0.begin();
Can0.setBaudRate(1000000);
Can0.setMaxMB(16);
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.onReceive(FIFO, canSniff); // I added FIFO to this
Can0.mailboxStatus();

This is the YouTube link to the Robot project That I'm working on.
https://www.youtube.com/channel/UCIChMYU0UEtZt9pezb02uHA
Thum5.jpg
 
Thank you tonton81!
anyway, with the following source code, Teensy4.0 can talk with my Honda FIT 2012 model year.
I have to enable FIFO and change MB1 to MB7. I did not check MB4 through MB7.

As you can see the part of can log, two ECU send Service$01 PID$05 response message to Teensy4.0.
Because I use a functional address 0x18DB33F1. This means a request to all emission related ECUs.
0x18DAF11D and 0x18DAF111.
"18DB" means functional addressing. "33" means target address (all emission related ECUs)."F1" means offboard tester.
"18DA" means physical addressing. "F1" is target address and offboard tester as explained before.
"11" is engine ECU. "1D" means transmission ECU.

I think my understanding around around setMBFilter is still poor.


Code:
MB: 99  ID: 0x191  EXT: 0  LEN: 8 DATA: 1 0 0 9A 9A 0 7F 3D  
MB: 99  ID: 0x164  EXT: 0  LEN: 8 DATA: 4 0 40 4F 56 0 0 7  
MB: 99  ID: 0x18E  EXT: 0  LEN: 3 DATA: 0 0 10 0 56 0 0 7  
MB: 99  ID: 0x136  EXT: 0  LEN: 8 DATA: 40 0 0 12 0 0 0 25  
MB: 99  ID: 0x13A  EXT: 0  LEN: 8 DATA: 0 0 0 0 0 0 0 28  
MB: 99  ID: 0x13F  EXT: 0  LEN: 8 DATA: 0 83 1 29 0 0 0 2C  
MB: 99  ID: 0x17C  EXT: 0  LEN: 8 DATA: 0 0 4 90 0 0 0 25  
MB: 99  ID: 0x19B  EXT: 0  LEN: 5 DATA: 0 0 0 0 30 0 0 0  
MB: 99  ID: 0x1DC  EXT: 0  LEN: 4 DATA: 2 4 90 1E 30 0 0 0 canTx_OBD REQ sen
MB: 99  ID: 0x18DAF11D  EXT: 1  LEN: 8 DATA: 3 41 5 52 55 55 55 55  
OBD: Engine Coolant Temp: 42 c 
MB: 99  ID: 0x18DAF111  EXT: 1  LEN: 8 DATA: 3 41 5 52 55 55 55 55  
OBD: Engine Coolant Temp: 42 c 
MB: 99  ID: 0x158  EXT: 0  LEN: 8 DATA: 0 0 0 0 0 0 0 19  
MB: 99  ID: 0x191  EXT: 0  LEN: 8 DATA: 1 0 0 9A 9A 0 7F 0  
MB: 99  ID: 0x164  EXT: 0  LEN: 8 DATA: 4 0 40 4F 56 0 0 16  
MB: 99  ID: 0x21E  EXT: 0  LEN: 7 DATA: 0 0 0 2D 0 0 17 0



Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;

int engineCoolantTemp = 0; // Save the data here

void setup(){
  while (!Serial && millis() < 5000);
  Serial.begin(115200);
  can2.begin();
  can2.setBaudRate(500000);
  can2.setMBFilter(REJECT_ALL);
 // can2.setMBFilter(MB1, 0x7E8); // Standard CANID  ENG ECU -> TESTER
 can2.setMBFilter(MB7, 0x18DAF111, EXT); // Extended CANID  ENG ECU -> TESTER (Physical Addressing)

  can2.setMaxMB(16);
  can2.enableFIFO();
  can2.enableFIFOInterrupt();
  
  can2.enableMBInterrupt(MB7);
  can2.onReceive(canSniff);

}

const long loopDelay1 = 500; // Make a request every 500ms
unsigned long timeNow1 = 0;
void loop(){
 // can2.events();
  if (millis() > timeNow1 + loopDelay1)
    {
      timeNow1 = millis();
      canTx_OBD(); // Query data from CAN BUS via OBD
      //canTx_UDS(); // Query data from CAN BUS via UDS

    }
}


void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in
  Serial.println(" ");
  Serial.print("MB: ");
  Serial.print(msg.mb);
  Serial.print("  ID: 0x");
  Serial.print(msg.id, HEX);
  Serial.print("  EXT: ");
  Serial.print(msg.flags.extended);
  Serial.print("  LEN: ");
  Serial.print(msg.len);
  Serial.print(" DATA: ");
  for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(msg.buf[i], HEX);
      Serial.print(" ");
    }
    if (msg.buf[1] == 0x41 && msg.buf[2] == 0x05){     // SID$01 PID$05 Engine Coolant Temperature
        engineCoolantTemp = msg.buf[3] - 40;           // Offset -40(degC)
        Serial.println(" ");
        Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

    if (msg.buf[1] == 0x62 && msg.buf[2] == 0xf4 && msg.buf[3] == 0x05){     // Checking positive reponse
        engineCoolantTemp = msg.buf[4] - 40;
        Serial.println(" ");
        Serial.printf("UDS: Engine Coolant Temp: %d c", engineCoolantTemp);
    }

}


void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x02;     // Data Length 2byte
    msgTx.buf[1] = 0x01;     // Service$01
    msgTx.buf[2] = 0x05;     // PID $05 Engine Coolant Temperature
    msgTx.buf[3] = 0x55;        // Padding
    msgTx.buf[4] = 0x55;
    msgTx.buf[5] = 0x55; 
    msgTx.buf[6] = 0x55;
    msgTx.buf[7] = 0x55;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit 
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit 
    msgTx.flags.remote = 0;
    
    //msgTx.id = 0x7E0; // request header for OBD           // Physical Addressing Request to Engine ECU
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    can2.write(msgTx);
    Serial.println("canTx_OBD REQ sent"); 
  }

 void canTx_UDS(){ // Request function to ask for Engine Coolant Temp via UDS request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x03;      // Data Length
    msgTx.buf[1] = 0x22;      // SID$22 Request parameter by Data Identifier
    msgTx.buf[2] = 0xf4;      // 
    msgTx.buf[3] = 0x05;      // PID$05 is Engine Coolant Temperature
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0; 
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit
    
    msgTx.flags.remote = 0;
    //msgTx.id = 0x7E0; // request header for OBD
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    can2.write(msgTx); 
    Serial.println("canTx_UDS REQ sent"); 
  }
 
if you enable FIFO, you dont have any reception mailboxes, only 8 TX mailboxes MB8-MB15. Because you are using FIFO without mailboxes you should use setFIFOFilter(0, 0x18DAF111,EXT)... 0 for 1st fifo filter.

MB99 is actually FIFO

You could add mailboxes with FIFO as well for RX, or reconfigure some TX as RX, it's very customizable. Example you could have the specific ECU frame saved in an interrupt mailbox while FIFO captures everything else in polling (non-interrupt) mode (for less critical data)

Also whenever you toggle the FIFO on or off, it resets all settings, so you need to set a filter AFTER switching FIFO on or off

since MB7 is part of the FIFO layer, it's no longer a mailbox, and calling setMBFilter and enableMBInterrupt on it will do nothing at all since it doesn't exist

From the main github page:
Code:
myCan.setFIFOFilter(0, 0x123, STD); // Set filter0 to allow STANDARD CAN ID 0x123 to be collected by FIFO.
myCan.setFIFOFilter(1, 0x456, EXT); // Set filter1 to allow EXTENDED CAN ID 0x456 to be collected by FIFO.
myCan.setMBFilter(MB6, 0x123); // Set mailbox 6 to allow CAN ID 0x123 to be collected. 

myCan.setMB(MB9,TX); // Set mailbox as transmit
myCan.setMB(MB10,RX,EXT); // Set mailbox as receiving extended frames.
myCan.setMB(MB11,RX,STD); // Set mailbox as receiving standard frames.

also, use set[COLOR="#FF0000"]FIFO[/COLOR]Filter(REJECT_ALL)

myCan.mailboxStatus(); // view current configuration
 
Last edited:
Thank you tonton81.

Instead of using setMBFilter(MB7, 0x18DAF111, EXT), but I try to use setFIFOFilter(0, 0x18DAF111,EXT).
Things are going forward and nicer.
 
You can have up to 8 FIFO filters (0-7) by default, 8 more after sacrificing 2 mailboxes (0-15), which would leave you with 6 TX mailboxes instead of default 8. It's a bit complex but highly customizable. FIFO has 6 receptions max before overflowing, but that should never happen with interrupts enabled and filters set

You'll also notice setFIFOFilter needs to specify STD/EXT, thats because the FIFO filter can receive either one, while setMBFilter we don't specify STD/EXT because the mailbox is configured to one or the other, and the filter is only applied based on the ID of the receiving frame only
 
Last edited:
TEENSY 4.1 CAN bus question about speed?

The CAN bus is working perfectly except it seems to only update every 0.5 seconds and I dont know why :( You can see in the code that I have the BaudRate set to 1000000 so I don't know why its updating so slow.

Maybe something is wrong with my setup code?

#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

Can0.begin();
Can0.setBaudRate(1000000);
Can0.setMaxMB(16);
Can0.enableFIFO();
Can0.enableFIFOInterrupt();
Can0.onReceive(FIFO, canSniff); // I added FIFO to this
Can0.mailboxStatus();

This is the YouTube link to the Robot project That I'm working on.
https://www.youtube.com/channel/UCIChMYU0UEtZt9pezb02uHA
View attachment 23335

what is slow? reception? transmission? code responses? how does the loop() code look like? are you using events()? if using events(), there may be a delay somewhere in your code before the queue can be read, if so try to disable events() (comment it out) and test it out. If you don't get any receptions after disabling events(), you need the latest library on github and it'll work
 
Things are going back and forth. Since engine coolant temperature changes slow, I used PID$0C engine speed.
I let Teensy4.0 transmit the SID$01 PID$0C request messages every 200ms but can receive only sometimes as you can see from the Arduino Log and Vehecile Spy Log.
From Vehicle Spy Log ECU send the response message every 200ms, but Teesnsy cannot pick up the response message every 200ms.
Is there any missing setting for FIFO?


Teensy4_PID0C_IDE.png

Teensy4_PID0C_PICT.png




Code:
#include <FlexCAN_T4.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ADC.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example
unsigned long curr, prev, next, interval;
int TW =0;

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16

FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;


static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };


int engineCoolantTemp = 0; // Save the data here
int engineRPM = 0;// Save the data here

void setup(){
  while (!Serial && millis() < 5000);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64

    delay(2000);
    
    Serial.println(F("SSD1306 allocation failed"));
    
    for(;;); // Don't proceed, loop forever
  }
  Serial.begin(115200);
  can2.begin();
  can2.setBaudRate(500000);
  can2.setMBFilter(REJECT_ALL);
 // can2.setMBFilter(MB1, 0x7E8); // Standard CANID  ENG ECU -> TESTER
  can2.setMBFilter(MB7, 0x18DB33F1, EXT); // Extended CANID  ENG ECU -> TESTER (Physical Addressing)
  can2.setFIFOFilter(0, 0x18DAF111,EXT); // Extended CANID  Target address F1(Tester), Sender 11(ENG ECU)

  can2.setMaxMB(16);
  can2.enableFIFO();
  can2.enableFIFOInterrupt();
  
  //can2.enableMBInterrupt(MB4);
  can2.onReceive(canSniff);

}

const long loopDelay1 = 200; // Make a request every 500ms
unsigned long timeNow1 = 0;

void loop(){
 can2.events();
  if (millis() > timeNow1 + loopDelay1)
    {
      timeNow1 = millis();
      canTx_OBD(); // Query data from CAN BUS via OBD
      //canTx_UDS(); // Query data from CAN BUS via UDS

    }
}


void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in
  if(msg.id == 0x18DAF111){
  Serial.println(" ");
  Serial.print("MB: ");
  Serial.print(msg.mb);
  Serial.print("  ID: 0x");
  Serial.print(msg.id, HEX);
  Serial.print("  EXT: ");
  Serial.print(msg.flags.extended);
  Serial.print("  LEN: ");
  Serial.print(msg.len);
  Serial.print(" DATA: ");
  for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(msg.buf[i], HEX);
      Serial.print(" ");
    }
  }
    if (msg.buf[1] == 0x41 && msg.buf[2] == 0x0C){     // SID$01 PID$05 Engine Coolant Temperature, PID$0C Engine Speed
        //engineCoolantTemp = msg.buf[3] - 40;           // Offset -40(degC)
        engineRPM = (msg.buf[3] * 0x100 + msg.buf[4])/4;   // Engine Speed 2byte 1/4 bit per rpm
        
        Serial.println(" ");
        //Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
        Serial.printf("OBD Engine Speed; %d rpm", engineRPM);
    }


    if(msg.id == 0x18DAF111){
      display.setTextColor(WHITE);
      display.clearDisplay();

      display.setTextSize(1);      // Normal 1:1 pixel scale
      display.setTextColor(SSD1306_WHITE); // Draw white text
      display.setCursor(0, 0);     // Start at top-left corner
      display.println(F("CAN_ID:"));
      display.setCursor(60,0);
      display.setTextColor(WHITE);
      display.print(msg.id, HEX);

    
      for ( uint8_t i = 0; i < 8; i++ ) {
         display.setCursor(15*i ,15);
         display.print(msg.buf[i],HEX);  Serial.print(" ");
      }

    }

      display.setTextSize(2);      // Normal 1:1 pixel scale
       display.setCursor(10, 30);
     //display.print(engineCoolantTemp,DEC);
      display.print(engineRPM, DEC);
      display.setCursor(70, 30);
     //display.print("degC");
      display.print("RPM");
     display.display(); 

      

}


void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x02;     // Data Length 2byte
    msgTx.buf[1] = 0x01;     // Service$01
    msgTx.buf[2] = 0x0C;     // PID $05 Engine Coolant Temperature
    msgTx.buf[3] = 0x55;        // Padding
    msgTx.buf[4] = 0x55;
    msgTx.buf[5] = 0x55; 
    msgTx.buf[6] = 0x55;
    msgTx.buf[7] = 0x55;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit 
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit 
    msgTx.flags.remote = 0;
    
    //msgTx.id = 0x7E0; // request header for OBD           // Physical Addressing Request to Engine ECU
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    can2.write(msgTx);
    Serial.println("canTx_OBD REQ sent"); 
  }


 
void testdrawchar(void) {
  display.clearDisplay();

  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  for(int16_t i=0; i<256; i++) {
    if(i == '\n') display.write(' ');
    else          display.write(i);
  }

  display.display();
  delay(2000);
}
 
remove EXT from setMBFilter (that function doesn't use that), remove events() from loop, and you enabled FIFO last in setup, which makes your filters not effective, also MB7 is a TX mailbox, so that function never runs and just exits, transmit mailboxes don't have filters.
 
This software worked like a champ after I changed my wiring to CAN1 on the Teensy 3.6. I'm using the Teensy 3.6 DIN rail adapter, and the Waveshare transceiver. I'd say this setup is one of the hidden GEMs in CAN World.

I'd developed a car data logger for IGN and Batt to SDHC, and now I'd like to shuttle off the CAN data to the SDHC as well so that I can log timestamped CAN and battery voltage side by side. Any hints or pitfalls with this approach?

I'm not sure how I can contribute here, but I think I can. I've been developing automotive electronics since the mid 80's, mostly at an upper management level, so I know a fair amount about vehicle electrical systems, including CAN bus architectures. I haven't spent a lot of time until now directly pulling data off a CAN bus as a listener. Looking forward to getting further into this project.

Thank you for making this functionality available on a great platform (Teensy/Arduino).
 
only pitfall may be the SD latency if any. What most people do is fill a 512 buffer in ram then write that to SD while you continue logging to a different 512 buffer. You can do this with a standard array, or the built-in Circular_Buffer library included and used with FlexCAN_T4.

if you want a challenge, you could do a circular buffer 1024byte and after size() returns >= 512, pop 512bytes of the contents out to the file while the same buffer is being populated :)
 
Meanwhile I am trying to figure out the FIFO and mailboxes behavior, but there is still a lot of things to understand.
Most of the reason why the software does not work properly may come from setup().

Current behavior is, when the teensy is connected to the vehicle, teensy keeps sending request to the ECU, but teensy cannot pick the positive response from the ECU though the ECU is sending the response message. When teensy is disconnected from the ECU, Teensy picks once or twice the positive response message.
For starting the building the software, I made a simple dummy ECU (PIC18F) which responds to the teensy request messages and sends some meaningless data. But the actual vehicle CAN network bus load is much higher and there are a lot of data coming into the Teensy's buffer.

Code:
// 29bit extended OBD CAN Sketch
//
//  2012 Honda FIT
//  get Service$01 PID$0C Engine Speed
//

#include <FlexCAN_T4.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ADC.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16

static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };


int engineCoolantTemp = 0; // Save the data here
int engineRPM = 0;// Save the data here


void setup(){
  while (!Serial && millis() < 5000);
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64

    delay(200);
    
    Serial.println(F("SSD1306 allocation failed"));
    
    for(;;); // Don't proceed, loop forever
  }
  
  Serial.begin(115200);
  can2.begin();
  can2.setBaudRate(500000);
  can2.setFIFOFilter(REJECT_ALL);
  can2.setFIFOFilter(0, 0x18DAF111, EXT); // Extended CANID  Target address F1(Tester), Sender 11(ENG ECU)
  // can2.setMB(MB9,TX); // Set mailbox as transmit
  //can2.setMB(MB10,RX,EXT); // Set mailbox as receiving extended frames.
  can2.setMaxMB(16);
  can2.mailboxStatus(); // view current configuration
  
  can2.enableFIFO();
  can2.enableFIFOInterrupt();
  
  can2.onReceive(canSniff);

}

const long loopDelay1 = 100; // Make a request every 500ms
unsigned long timeNow1 = 0;

void loop(){
 //can2.events();
 
  if (millis() > timeNow1 + loopDelay1)
    {
      timeNow1 = millis();
      canTx_OBD(); // Query data from CAN BUS via OBD
      //canTx_UDS(); // Query data from CAN BUS via UDS

    }
}


void canSniff (const CAN_message_t &msg){ // Global callback to catch any CAN frame coming in

    if (msg.id == 0x18DAF111 & msg.buf[1] == 0x41 & msg.buf[2] == 0x0C){     // SID$01 PID$05 Engine Coolant Temperature
        //engineCoolantTemp = msg.buf[3] - 40;           // Offset -40(degC)
        engineRPM = (msg.buf[3]*0x100 + msg.buf[4]) /4;
        Serial.println(" ");
        //Serial.printf("OBD: Engine Coolant Temp: %d c", engineCoolantTemp);
        Serial.printf("OBD: Engine Speed: %d rpm", engineRPM);
    }

    if (msg.buf[1] == 0x62 && msg.buf[2] == 0xf4 && msg.buf[3] == 0x05){     // Checking positive reponse
        engineCoolantTemp = msg.buf[4] - 40;
        Serial.println(" ");
        Serial.printf("UDS: Engine Coolant Temp: %d c", engineCoolantTemp);
    }
        display.setTextColor(WHITE);
        display.clearDisplay();

        display.setTextSize(1);      // Normal 1:1 pixel scale
        display.setTextColor(SSD1306_WHITE); // Draw white text
        display.setCursor(0, 0);     // Start at top-left corner
        display.println(F("CAN_ID:"));
        display.setCursor(60,0);
        display.setTextColor(WHITE);
        display.print(msg.id, HEX);

    
        for ( uint8_t i = 0; i < 8; i++ ) {
           display.setCursor(15*i ,15);
           display.print(msg.buf[i],HEX);  Serial.print(" ");
        }

        display.setTextSize(2);      // Normal 1:1 pixel scale
        display.setCursor(10, 35);
       //display.print(engineCoolantTemp,DEC);
        display.print(engineRPM, DEC);
        display.setCursor(70, 35);
       //display.print("degC");
        display.print("RPM");
        display.display(); 

}


void canTx_OBD(){ // Request function to ask for Engine Coolant Temp via OBD request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x02;     // Data Length 2byte
    msgTx.buf[1] = 0x01;     // Service$01
    msgTx.buf[2] = 0x0C;     // PID $05 Engine Coolant Temperature
    msgTx.buf[3] = 0x55;        // Padding
    msgTx.buf[4] = 0x55;
    msgTx.buf[5] = 0x55; 
    msgTx.buf[6] = 0x55;
    msgTx.buf[7] = 0x55;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit 
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit 
    msgTx.flags.remote = 0;
    
    //msgTx.id = 0x7E0; // request header for OBD           // Physical Addressing Request to Engine ECU
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    can2.write(msgTx);
    Serial.println("canTx_OBD REQ sent"); 
  }

 void canTx_UDS(){ // Request function to ask for Engine Coolant Temp via UDS request
  CAN_message_t msgTx, msgRx;
    msgTx.buf[0] = 0x03;      // Data Length
    msgTx.buf[1] = 0x22;      // SID$22 Request parameter by Data Identifier
    msgTx.buf[2] = 0xf4;      // 
    msgTx.buf[3] = 0x05;      // PID$05 is Engine Coolant Temperature
    msgTx.buf[4] = 0;
    msgTx.buf[5] = 0; 
    msgTx.buf[6] = 0; 
    msgTx.buf[7] = 0;
    msgTx.len = 8;            // number of bytes in request
    //msgTx.flags.extended = 0; // 11 bit header, not 29 bit
    msgTx.flags.extended = 1; // 29 bit header, not 11 bit
    
    msgTx.flags.remote = 0;
    //msgTx.id = 0x7E0; // request header for OBD
    msgTx.id = 0x18DB33F1; // request header for OBD Functional Addressing request to all emission related ECUs.
    can2.write(msgTx); 
    Serial.println("canTx_UDS REQ sent"); 
  }



void testdrawchar(void) {
  display.clearDisplay();

  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0, 0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  for(int16_t i=0; i<256; i++) {
    if(i == '\n') display.write(' ');
    else          display.write(i);
  }

  display.display();
  delay(2000);
}
 
dont set filters BEFORE calling enableFIFO

and by the way.....
Code:
msg.id == 0x18DAF111 & msg.buf[1] == 0x41 & msg.buf[2]

& is not && :)

essentially you are asking:
Code:
msg.id == (0x18DAF111 & msg.buf[1]) == (0x41 & msg.buf[2]).....
which would result in 0 in the end, which is why the condition is never met
 
Last edited:
Back
Top