Forum Rule: Always post complete source code & details to reproduce any issue!
Page 45 of 46 FirstFirst ... 35 43 44 45 46 LastLast
Results 1,101 to 1,125 of 1135

Thread: FlexCAN_T4 - FlexCAN for Teensy 4

  1. #1101
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    Looks like I needed to add this to both the sender and receiver to use the longer length:

    Code:
    can3.setRegions(64);

  2. #1102
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    I've got it working with 2MBaud. Not sure how to go higher and still have everything work reliably. I have 8 MBaud transceivers, 120 Ohm terminators and a twister pair of wires between the boards with a length of about 6 inches. Then again, I'm unsure what all of the flags in the CANFD_timings_t struct mean. Could anyone shed light on the CANFD_timings_t struct members and what each does?

    Thanks much!

  3. #1103
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    Circling back that I got this working up to 5 Mb/s by setting the peripheral clock to 60 MHz after reading this thread:
    https://forum.pjrc.com/threads/67261...l=1#post279951

    EDIT: Actually, I can get 6 MB/s. Not sure what's preventing reaching 8 MB/s.
    Last edited by brtaylor; 11-20-2022 at 10:09 PM.

  4. #1104
    Senior Member skpang's Avatar
    Join Date
    Jan 2015
    Location
    UK
    Posts
    223
    I've got it working at 10Mbps with these settings:

    Code:
      FD.begin();
      CANFD_timings_t config;
      config.clock = CLK_80MHz;
      config.baudrate =   1000000;     // 1000kbps Nominal data rate
      config.baudrateFD = 10000000;    // 10000kpbs Data rate
      config.propdelay = 190;
      config.bus_length = 1;
      config.sample = 70;
      FD.setRegions(64);
      FD.setBaudRate(config);
    Tested with the PCAN-USB Pro from Peak System.

    Click image for larger version. 

Name:	IMG_8800.jpg 
Views:	28 
Size:	99.6 KB 
ID:	29788
    Click image for larger version. 

Name:	192_168_1_28.jpg 
Views:	36 
Size:	126.2 KB 
ID:	29789

    Cable length is about 5m between the two Teensy boards.
    Teensy 4.0 is fast !!

  5. #1105
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    Thanks, updating the peripheral clock to 80 MHz does enable 8 Mb/s to work for me too.

  6. #1106
    Greetings --

    New to the board. Is there a more detailed programming document for this library available other than what is posted on GitHub?
    Thanks

  7. #1107
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,020
    Quote Originally Posted by pinnaclesystemsgroup View Post
    Greetings --

    New to the board. Is there a more detailed programming document for this library available other than what is posted on GitHub?
    Thanks
    What Library? We are NOT mind readers!!
    Oh, I guess you mean FlexCan. Other than the examples, I doubt it.

  8. #1108
    Junior Member
    Join Date
    Nov 2012
    Posts
    3
    Quote Originally Posted by pinnaclesystemsgroup View Post
    Greetings --

    New to the board. Is there a more detailed programming document for this library available other than what is posted on GitHub?
    Thanks

    I have a youtube demo (source in the description) https://www.youtube.com/watch?v=N8t9_0dAKvQ

  9. #1109
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    Quote Originally Posted by pinnaclesystemsgroup View Post
    Greetings --

    New to the board. Is there a more detailed programming document for this library available other than what is posted on GitHub?
    Thanks
    It's a great library; although, I do wish the documentation was more detailed. Especially with how many tuning knobs and options there are. Of course, we're all free to submit pull requests with additions to the README...

  10. #1110
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    I've run into another stumbling block. I'm trying to receive CAN-FD messages in an interrupt context.

    Example sender code is:

    Code:
    #include <FlexCAN_T4.h>
    #include <elapsedMillis.h>
    
    FlexCAN_T4FD<CAN3, RX_SIZE_256, TX_SIZE_128> can;
    elapsedMillis t_ms;
    CANFD_message_t msg;
    
    void setup() {
      can.begin();
      CANFD_timings_t cfg;
      cfg.clock = CLK_80MHz;
      cfg.baudrate = 1000000;
      cfg.baudrateFD = 8000000;
      cfg.propdelay = 190;
      cfg.bus_length = 1;
      cfg.sample = 70;
      can.setRegions(64);
      can.setBaudRate(cfg);
      msg.id = 0x01;
      msg.len = 5;
      Serial.begin(115200);
      delay(1000);
    }
    
    void loop() {
      if (t_ms >= 1000) {
        t_ms = 0;
        msg.buf[0]++;
        can.write(msg);
      }
    }
    Receiver code is:

    Code:
    #include <FlexCAN_T4.h>
    FlexCAN_T4FD<CAN3, RX_SIZE_256, TX_SIZE_64> can;
    CANFD_message_t msg;
    
    void setup(void) {
      Serial.begin(115200);
      delay(400);
      can.begin();
      CANFD_timings_t cfg;
      cfg.clock = CLK_80MHz;
      cfg.baudrate = 1000000;
      cfg.baudrateFD = 8000000;
      cfg.propdelay = 190;
      cfg.bus_length = 1;
      cfg.sample = 70;
      can.setRegions(64);
      can.setBaudRate(cfg);
      can.setMBFilter(REJECT_ALL);
      can.enableMBInterrupts();
      can.onReceive(MB0, isr);
      can.setMBFilterRange(MB0, 0x00, 0xFF);
      can.mailboxStatus();
    }
    
    void isr(const CANFD_message_t &msg) {
      Serial.println("RECEIVED INT");
    }
    
    void loop() {
      if (can.read(msg)) {
        Serial.println("RECEIVED LOOP");
      }
    }
    My expectation is that I would see "RECEIVED INT" in the serial monitor, but I don't. I don't really care to do anything fancy with the mailboxes, I just want to receive all of the messages in the interrupt context because I plan to use the loop to do some other tasks. I would use the FIFO, but my understanding is that CAN-FD doesn't have a FIFO buffer (even though there is an enableFIFO method, so maybe my assumption is wrong). What do I need to do to make this work?

    If I comment the following lines from setup, then I can receive the message in loop with "RECEIVED LOOP" printed to the serial monitor, which shows that my hardware setup is correct.

    Code:
      can.setMBFilter(REJECT_ALL);
      can.enableMBInterrupts();
      can.onReceive(MB0, isr);
      can.setMBFilterRange(MB0, 0x00, 0xFF);
      can.mailboxStatus();

  11. #1111
    Hello,

    Haven't hit this issue yet. Perhaps some ideas on making this code work could be found in the example code:

    mailbox_filtering_example_with_interrupts

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

    #define NUM_TX_MAILBOXES 2
    #define NUM_RX_MAILBOXES 6
    void setup(void) {
    Serial.begin(115200); delay(400);
    Can0.begin();
    Can0.setBaudRate(250000);
    Can0.setMaxMB(NUM_TX_MAILBOXES + NUM_RX_MAILBOXES);
    for (int i = 0; i<NUM_RX_MAILBOXES; i++){
    Can0.setMB(i,RX,EXT);
    }
    for (int i = NUM_RX_MAILBOXES; i<(NUM_TX_MAILBOXES + NUM_RX_MAILBOXES); i++){
    Can0.setMB(i,TX,EXT);
    }
    Can0.setMBFilter(REJECT_ALL);
    Can0.enableMBInterrupts();
    Can0.onReceive(MB0,canSniff);
    Can0.onReceive(MB1,canSniff);
    Can0.onReceive(MB2,canSniff);
    Can0.setMBFilterProcessing(MB0,0x00,0xFF);
    Can0.setMBFilterProcessing(MB1,0x03,0xFF);
    Can0.setMBFilterProcessing(MB2,0x0B,0xFF);
    Can0.mailboxStatus();
    }

    void canSniff(const CAN_message_t &msg) {
    Serial.print("MB "); Serial.print(msg.mb);
    Serial.print(" OVERRUN: "); Serial.print(msg.flags.overrun);
    Serial.print(" LEN: "); Serial.print(msg.len);
    Serial.print(" EXT: "); Serial.print(msg.flags.extended);
    Serial.print(" TS: "); Serial.print(msg.timestamp);
    Serial.print(" ID: "); Serial.print(msg.id, HEX);
    Serial.print(" Buffer: ");
    for ( uint8_t i = 0; i < msg.len; i++ ) {
    Serial.print(msg.buf[i], HEX); Serial.print(" ");
    } Serial.println();
    }

    void loop() {
    Can0.events();
    }

  13. #1113
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    Quote Originally Posted by pinnaclesystemsgroup View Post
    Hello,

    Haven't hit this issue yet. Perhaps some ideas on making this code work could be found in the example code:

    mailbox_filtering_example_with_interrupts
    Thanks, I saw that and it works for CAN 2.0. I think there must be something with CAN-FD and the mailboxes / interrupts that I'm not understanding.

  14. #1114
    Senior Member
    Join Date
    Aug 2018
    Location
    Brisbane, Australia
    Posts
    146
    Quote Originally Posted by brtaylor View Post
    I've run into another stumbling block. I'm trying to receive CAN-FD messages in an interrupt context.

    Example sender code is:

    Code:
    void isr(const CANFD_message_t &msg) {
      Serial.println("RECEIVED INT");
    }
    My expectation is that I would see "RECEIVED INT" in the serial monitor, but I don't. I don't really care to do anything fancy with the mailboxes, I just want to receive all of the messages in the interrupt context because I plan to use the loop to do some other tasks. I would use the FIFO, but my understanding is that CAN-FD doesn't have a FIFO buffer (even though there is an enableFIFO method, so maybe my assumption is wrong). What do I need to do to make this work?
    This may not be related to your problem but I have experienced extremely weird behaviour when trying to call Serial.println() from an ISR. You might try toggling a LED instead to see if the ISR is being called.

  15. #1115
    It's my understanding the MCP2517FD chip logic controller code has and SPI command interface in the FlexCAN SPI code that sets the FD message send and recieve processing by mailboxes and interrupts.

    Interrupts are intended to control and signal the mailbox events as they occor and are processed and the priorities of those send and recieve chip events for the mailboxes connevted to the FD CAN message bus.

    FIFO processing is handled at the chip level (see the Microchip documentation) where the chip logic stages and controls the internal messaging buffers are used by send and recieve message commands. FIFO mailboxes for FD CAN 2.0B is recommended in most automotive CAN Bus designs.

  16. #1116
    From:
    FlexCAN_T4.h


    typedef*struct*CANFD_timings_t*{
    **double*baudrate*=*1000000;
    **double*baudrateFD*=*2000000;
    **double*propdelay*=*190;
    **double*bus_length*=*1;
    **double*sample*=*75;
    **FLEXCAN_CLOCK*clock*=*CLK_24MHz;*
    }*CANFD_timings_t;

    You are referring to this when you asked for an explanation..?

    Taken from:

    https://github.com/tonton81/FlexCAN_...r/FlexCAN_T4.h

  17. #1117
    Just FYI --

    According to the FLEXCAN docs on GitHub..

    Note that there is no FIFO support in CANFD for Teensy 4.0. FIFO is only supported in CAN2.0 mode on Teensy 3.x and Teensy 4.0

  18. #1118
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,020
    Code:
    #include <FlexCAN_T4.h>
    FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;
    
    #define NUM_TX_MAILBOXES 2
    #define NUM_RX_MAILBOXES 6
    void setup(void) {
    	Serial.begin(115200); delay(400);
    	Can0.begin();
    	Can0.setBaudRate(250000);
    	Can0.setMaxMB(NUM_TX_MAILBOXES + NUM_RX_MAILBOXES);
    	for (int i = 0; i < NUM_RX_MAILBOXES; i++) {
    		Can0.setMB(i, RX, EXT);
    	}
    	for (int i = NUM_RX_MAILBOXES; i < (NUM_TX_MAILBOXES + NUM_RX_MAILBOXES); i++) {
    		Can0.setMB(i, TX, EXT);
    	}
    	Can0.setMBFilter(REJECT_ALL);
    	Can0.enableMBInterrupts();
    	Can0.onReceive(MB0, canSniff);
    	Can0.onReceive(MB1, canSniff);
    	Can0.onReceive(MB2, canSniff);
    	Can0.setMBFilterProcessing(MB0, 0x00, 0xFF);
    	Can0.setMBFilterProcessing(MB1, 0x03, 0xFF);
    	Can0.setMBFilterProcessing(MB2, 0x0B, 0xFF);
    	Can0.mailboxStatus();
    }
    
    void canSniff(const CAN_message_t& msg) {
    	Serial.print("MB "); Serial.print(msg.mb);
    	Serial.print(" OVERRUN: "); Serial.print(msg.flags.overrun);
    	Serial.print(" LEN: "); Serial.print(msg.len);
    	Serial.print(" EXT: "); Serial.print(msg.flags.extended);
    	Serial.print(" TS: "); Serial.print(msg.timestamp);
    	Serial.print(" ID: "); Serial.print(msg.id, HEX);
    	Serial.print(" Buffer: ");
    	for (uint8_t i = 0; i < msg.len; i++) {
    		Serial.print(msg.buf[i], HEX); Serial.print(" ");
    	} Serial.println();
    }
    
    void loop() {
    	Can0.events();
    }
    Can you please enclose any posted code between CODE tags using the # button at the top of the post form.
    It presents your work in a much more readable and understandable manner making it much easier for people to help you.

  19. #1119
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Santa Fe, NM
    Posts
    809
    Quote Originally Posted by brtaylor View Post
    I've run into another stumbling block. I'm trying to receive CAN-FD messages in an interrupt context.

    Example sender code is:

    Code:
    #include <FlexCAN_T4.h>
    #include <elapsedMillis.h>
    
    FlexCAN_T4FD<CAN3, RX_SIZE_256, TX_SIZE_128> can;
    elapsedMillis t_ms;
    CANFD_message_t msg;
    
    void setup() {
      can.begin();
      CANFD_timings_t cfg;
      cfg.clock = CLK_80MHz;
      cfg.baudrate = 1000000;
      cfg.baudrateFD = 8000000;
      cfg.propdelay = 190;
      cfg.bus_length = 1;
      cfg.sample = 70;
      can.setRegions(64);
      can.setBaudRate(cfg);
      msg.id = 0x01;
      msg.len = 5;
      Serial.begin(115200);
      delay(1000);
    }
    
    void loop() {
      if (t_ms >= 1000) {
        t_ms = 0;
        msg.buf[0]++;
        can.write(msg);
      }
    }
    Receiver code is:

    Code:
    #include <FlexCAN_T4.h>
    FlexCAN_T4FD<CAN3, RX_SIZE_256, TX_SIZE_64> can;
    CANFD_message_t msg;
    
    void setup(void) {
      Serial.begin(115200);
      delay(400);
      can.begin();
      CANFD_timings_t cfg;
      cfg.clock = CLK_80MHz;
      cfg.baudrate = 1000000;
      cfg.baudrateFD = 8000000;
      cfg.propdelay = 190;
      cfg.bus_length = 1;
      cfg.sample = 70;
      can.setRegions(64);
      can.setBaudRate(cfg);
      can.setMBFilter(REJECT_ALL);
      can.enableMBInterrupts();
      can.onReceive(MB0, isr);
      can.setMBFilterRange(MB0, 0x00, 0xFF);
      can.mailboxStatus();
    }
    
    void isr(const CANFD_message_t &msg) {
      Serial.println("RECEIVED INT");
    }
    
    void loop() {
      if (can.read(msg)) {
        Serial.println("RECEIVED LOOP");
      }
    }
    My expectation is that I would see "RECEIVED INT" in the serial monitor, but I don't. I don't really care to do anything fancy with the mailboxes, I just want to receive all of the messages in the interrupt context because I plan to use the loop to do some other tasks. I would use the FIFO, but my understanding is that CAN-FD doesn't have a FIFO buffer (even though there is an enableFIFO method, so maybe my assumption is wrong). What do I need to do to make this work?

    If I comment the following lines from setup, then I can receive the message in loop with "RECEIVED LOOP" printed to the serial monitor, which shows that my hardware setup is correct.

    Code:
      can.setMBFilter(REJECT_ALL);
      can.enableMBInterrupts();
      can.onReceive(MB0, isr);
      can.setMBFilterRange(MB0, 0x00, 0xFF);
      can.mailboxStatus();
    FYI, I just wanted to follow up that I've been working this issue on GitHub here:
    https://github.com/tonton81/FlexCAN_T4/issues/56

    Just in case someone runs into a similar problem and is looking for a solution. I'm suspecting that it's a bug in the library and issued a pull request with a fix.

  20. #1120
    Junior Member
    Join Date
    Nov 2022
    Posts
    1
    Hi!

    I'm trying to use can bus FD on my Teensy 4.0 thriple can bus board to send frames to rsp3, but it doesn't show any message while I use candump can0 on my rsp3. Can you help me out? Thx!!
    I'm using the demo code below:

    #include <FlexCAN_T4.h>

    FlexCAN_T4FD<CAN3, RX_SIZE_256, TX_SIZE_16> FD; // can3 port



    IntervalTimer timer;
    uint8_t d=0;

    void setup(void) {

    Serial.begin(115200); delay(1000);
    Serial.println("Teensy 4.0 Triple CAN test");

    FD.begin();
    CANFD_timings_t config;
    config.clock = CLK_24MHz;
    config.baudrate = 500000; // 500kbps arbitration rate
    config.baudrateFD = 2000000; // 2000kbps data rate
    config.propdelay = 190;
    config.bus_length = 1;
    config.sample = 75;
    FD.setRegions(64);
    FD.setBaudRateAdvanced(config, 1, 1);
    FD.onReceive(canSniff);
    FD.setMBFilter(ACCEPT_ALL);
    FD.setMBFilter(MB13, 0x1);
    FD.setMBFilter(MB12, 0x1, 0x3);
    FD.setMBFilterRange(MB8, 0x1, 0x04);
    FD.enableMBInterrupt(MB8);
    FD.enableMBInterrupt(MB12);
    FD.enableMBInterrupt(MB13);
    FD.enhanceFilter(MB8);
    FD.enhanceFilter(MB10);
    FD.distribute();
    FD.mailboxStatus();


    timer.begin(sendframe, 500000); // Send frame every 500ms
    }

    void sendframe()
    {
    CANFD_message_t msg;
    msg.len = 64;
    msg.id = 0x4fd;
    msg.seq = 1;
    for ( uint8_t i = 0; i < 64; i++ ) {
    msg.buf[i] = i + 1;
    //Serial.println(i);
    }
    msg.buf[0] = d;
    FD.write(msg); // write to can3
    //Serial.println();
    }


    void canSniff(const CANFD_message_t &msg) {
    Serial.print("ISR - MB "); Serial.print(msg.mb);
    Serial.print(" OVERRUN: "); Serial.print(msg.flags.overrun);
    Serial.print(" LEN: "); Serial.print(msg.len);
    Serial.print(" EXT: "); Serial.print(msg.flags.extended);
    Serial.print(" TS: "); Serial.print(msg.timestamp);
    Serial.print(" ID: "); Serial.print(msg.id, HEX);
    Serial.print(" Buffer: ");
    for ( uint8_t i = 0; i < msg.len; i++ ) {
    Serial.print(msg.buf[i], HEX); Serial.print(" ");
    } Serial.println();
    }

    void loop() {

    CANFD_message_t msg;

    FD.events(); /* needed for sequential frame transmit and callback queues */
    if ( FD.readMB(msg) ) {
    Serial.print("MB: "); Serial.print(msg.mb);
    Serial.print(" OVERRUN: "); Serial.print(msg.flags.overrun);
    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(" BRS: "); Serial.print(msg.brs);
    Serial.print(" EDL: "); Serial.print(msg.edl);
    Serial.print(" DATA: ");
    for ( uint8_t i = 0; i <msg.len ; i++ ) {
    Serial.print(msg.buf[i]); Serial.print(" ");
    }
    Serial.print(" TS: "); Serial.println(msg.timestamp);
    }
    }

  21. #1121
    Junior Member
    Join Date
    Dec 2021
    Posts
    1
    Hi All,

    I have been doing searching and haven't managed to find it anywhere so thought I would ask here. I have a Teensy 4.1 that I am using as a body/chassis ECU that sends data to a Raspberry Pi for a digital dash in my car. I am switching from an OEM ECU using OBD to an aftermarket ECU. The new ECU uses Haltech CAN bus protocol. Does anyone know how I alter the code so that the Teensy will read the Haltech CAN bus messages? I have added the code from Arduino IDE below. Many Thanks in advance

    Code:
     #ifndef CANBUS_H
    #define CANBUS_H
    
    #include <FlexCAN_T4.h>
    #include "values.h"
    
    extern FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
    extern Values values;
    
    void canSend(uint8_t activeByte){
      CAN_message_t msgTx;
      msgTx.len = 3; // number of bytes in request
      msgTx.id = 0x7E0; // Request Header
      //  msgTx.flags.extended = 0; // 11 bit header, not 29 bit
      //  msgTx.flags.remote = 0;
      msgTx.buf[0] = 0x02; // Number of bytes in request
      msgTx.buf[1] = 0x01; // Mode of request (0x01 = OBD2)
      msgTx.buf[2] = activeByte;
      msgTx.buf[4] = 0x00;
      msgTx.buf[5] = 0x00; 
      msgTx.buf[6] = 0x00;
      msgTx.buf[7] = 0x00;
      can1.write(msgTx); 
    }
    
    void canReceive(const CAN_message_t &msg){
    //  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(" ");
    //  }
    //  Serial.println("");
    
      // Handle mode 41 messages
      if (msg.id == 0x7E8 && msg.buf[1] == 0x41) {
        switch (msg.buf[2]) {
    
          // RPM
          case 0x0c: {
            if (msg.buf[0] == 4) {
              values.rpm = ((msg.buf[3] * 256 + msg.buf[4]) / 4);
            }
          }
          break;
    
          // Coolant
          case 0x05: {
            if (msg.buf[0] == 3) {
              values.coolantTemp = (int)((((float)msg.buf[3] - 40.0f) * 1.8f) + 32.0f);
            }
          }
          break;
    
          // MAP
          case 0x0B: {
            if (msg.buf[0] == 3) {
              values.boostPressure = ((float)msg.buf[3] * 0.145038f) - values.barometricPressure;
            }
          }
          break;
    
          // Barometric pressure
          case 0x33: {
            if (msg.buf[0] == 3) {
              values.barometricPressure = (float)msg.buf[3] * 0.145038f;
            }
          }
          break;
          
        }
      }
    
      // Engine Fluid Level/Pressure 1
      if (msg.id == 0x18FEEF00) {
        // Oil pressure
        values.oilPressure = (float)msg.buf[3] * 4.0f * 0.145038f;
      }
    }
    
    void canInit() {
      can1.begin();
      can1.setBaudRate(500000);
      can1.enableFIFO();
      can1.enableFIFOInterrupt();
      can1.onReceive(canReceive);
    }
    
    #endif
    Some info on Haltech:
    Key Information
    The Haltech CAN bus operates at 1MBit and uses 11-bit IDs. IDs are expressed in Hexadecimal.
    The first byte in a packet is considered byte 0, and the 8th byte is byte 7. The most significant bit in a byte is considered bit 7 and the least significant bit is
    bit 0.
    Data is encoded as big endian.
    Click image for larger version. 

Name:	haltech example.JPG 
Views:	11 
Size:	50.3 KB 
ID:	30082
    Last edited by mikesmif; 01-04-2023 at 11:17 AM.

  22. #1122
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,020
    This is something I found when Googling Haltech Can Protocol.

  23. #1123
    Quote Originally Posted by mikesmif View Post
    Hi All,

    I have been doing searching and haven't managed to find it anywhere so thought I would ask here. I have a Teensy 4.1 that I am using as a body/chassis ECU that sends data to a Raspberry Pi for a digital dash in my car. I am switching from an OEM ECU using OBD to an aftermarket ECU. The new ECU uses Haltech CAN bus protocol. Does anyone know how I alter the code so that the Teensy will read the Haltech CAN bus messages? I have added the code from Arduino IDE below. Many Thanks in advance

    Code:
     #ifndef CANBUS_H
    #define CANBUS_H
    
    #include <FlexCAN_T4.h>
    #include "values.h"
    
    extern FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
    extern Values values;
    
    void canSend(uint8_t activeByte){
      CAN_message_t msgTx;
      msgTx.len = 3; // number of bytes in request
      msgTx.id = 0x7E0; // Request Header
      //  msgTx.flags.extended = 0; // 11 bit header, not 29 bit
      //  msgTx.flags.remote = 0;
      msgTx.buf[0] = 0x02; // Number of bytes in request
      msgTx.buf[1] = 0x01; // Mode of request (0x01 = OBD2)
      msgTx.buf[2] = activeByte;
      msgTx.buf[4] = 0x00;
      msgTx.buf[5] = 0x00; 
      msgTx.buf[6] = 0x00;
      msgTx.buf[7] = 0x00;
      can1.write(msgTx); 
    }
    
    void canReceive(const CAN_message_t &msg){
    //  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(" ");
    //  }
    //  Serial.println("");
    
      // Handle mode 41 messages
      if (msg.id == 0x7E8 && msg.buf[1] == 0x41) {
        switch (msg.buf[2]) {
    
          // RPM
          case 0x0c: {
            if (msg.buf[0] == 4) {
              values.rpm = ((msg.buf[3] * 256 + msg.buf[4]) / 4);
            }
          }
          break;
    
          // Coolant
          case 0x05: {
            if (msg.buf[0] == 3) {
              values.coolantTemp = (int)((((float)msg.buf[3] - 40.0f) * 1.8f) + 32.0f);
            }
          }
          break;
    
          // MAP
          case 0x0B: {
            if (msg.buf[0] == 3) {
              values.boostPressure = ((float)msg.buf[3] * 0.145038f) - values.barometricPressure;
            }
          }
          break;
    
          // Barometric pressure
          case 0x33: {
            if (msg.buf[0] == 3) {
              values.barometricPressure = (float)msg.buf[3] * 0.145038f;
            }
          }
          break;
          
        }
      }
    
      // Engine Fluid Level/Pressure 1
      if (msg.id == 0x18FEEF00) {
        // Oil pressure
        values.oilPressure = (float)msg.buf[3] * 4.0f * 0.145038f;
      }
    }
    
    void canInit() {
      can1.begin();
      can1.setBaudRate(500000);
      can1.enableFIFO();
      can1.enableFIFOInterrupt();
      can1.onReceive(canReceive);
    }
    
    #endif
    Some info on Haltech:
    Key Information
    The Haltech CAN bus operates at 1MBit and uses 11-bit IDs. IDs are expressed in Hexadecimal.
    The first byte in a packet is considered byte 0, and the 8th byte is byte 7. The most significant bit in a byte is considered bit 7 and the least significant bit is
    bit 0.
    Data is encoded as big endian.
    Click image for larger version. 

Name:	haltech example.JPG 
Views:	11 
Size:	50.3 KB 
ID:	30082
    The general idea is to replace your canRecieve function with code that just checks for IDs you want. If ID matches 0x361 (for example), grab the correct bytes and join them, then convert to physical units. Also, be sure to correct the baud rate in canInit.

    Here's an example of how to get oilPressure:
    Code:
    void canReceive(const CAN_message_t &msg){
      // Handle 0x361 messages (~50Hz)
      if (msg.id == 0x361) {
    	  
    	// Oil Pressure
    	values.oilPressure = (float)(msg.buf[2]<<8 + msg.buf[3])/10.0f - 101.3f;
      }
    }
    *Note: I haven't checked or tested this code in any way*

    If the numbers you are receiving don't make sense, try switching the byte order.

  24. #1124
    Junior Member
    Join Date
    Jan 2023
    Posts
    1
    Hi, I have been succesfully using Teensy 4.0's as the can bridges based on modified code of the samples. Works great with 500k speed. But now I am struggling with the same software and hardware but using 83.3k speed. I have tried different clock speeds, bu no difference. by plugging in the device, seem to halt the canbus traffic.

    Code:
    #include <FlexCAN_T4.h>
    
    FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
    CAN_message_t msg;
    
    void setup(void) {
      Serial.begin(115200); delay(400);
      pinMode(2, OUTPUT); digitalWrite(2, LOW); /* optional tranceiver enable pin */
      pinMode(3, OUTPUT); digitalWrite(3, LOW); /* optional tranceiver enable pin */
      can1.begin();
      can1.setClock(CLK_60MHz);
    //  can1.setBaudRate(500000);
      can1.setBaudRate(83330);
      can2.begin();
      can2.setClock(CLK_60MHz);
    //  can2.setBaudRate(500000);
      can2.setBaudRate(83330);
    }
    
    void loop() {
        if ( can1.read(msg) ) {
          Serial.print("CAN1 "); 
          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]); Serial.print(" ");
          }
          Serial.print("  TS: "); Serial.println(msg.timestamp);
          can2.write(msg); // echo to can2
      }
      else if ( can2.read(msg) ) {
        Serial.print("CAN2 "); 
        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]); Serial.print(" ");
        }
        Serial.print("  TS: "); Serial.println(msg.timestamp);
      }
    }
    Any tips, what is it I am missing here?

    Thanks!

  25. #1125
    Hi not sure if this is the right place, but I set up a CAN logger, but I want to start and stop with a pushbutton. I've been able to start it on command, but it won't shut off. How would I deconstruct/disable the CAN object?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •