Forum Rule: Always post complete source code & details to reproduce any issue!
Page 43 of 45 FirstFirst ... 33 41 42 43 44 45 LastLast
Results 1,051 to 1,075 of 1120

Thread: FlexCAN_T4 - FlexCAN for Teensy 4

  1. #1051
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    @tony could you help me write a simple sketch with the isotp addon?

    Today I am using MBs and three different callbacks (each per ID)
    I would like to send the following frame:
    0x07, 0x22, 0xF4, 0x33, 0xF4, 0x0F, 0xF4, 0x3C
    Response would be
    0x10, 0x0D,0x62, 0xF4, 0x33, 0x00, 0xF4, 0x0F, 0x00, 0xF4, 0x3C, 0x00, 0x00, 0x00, 0x00

    At the moment when I receive the fist frame I send a flow control, then get the rest of the payload.
    How would I manage this in isotp? I recall there is no support for mailboxes and I would have to check the ID in the general isotp callback - is this still the case?
    Is there no way to assign an isotp callback per mailbox?

  2. #1052
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    isotp plugin doesn't use mailboxes specifically, as the data comes in it from the controller goes to the background reassembly queue until it is complete, until which it it then fires the user callback

    a send receive example can be found in the examples folder:
    https://github.com/tonton81/FlexCAN_...nd_receive.ino

  3. #1053
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    Ive seen the example, but what’s not clear is do I have to send the flow control to the ECU or does the library do that when it receives the first frame?

  4. #1054
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    ahh i see. the way the library handles isotp between teensies is it sends the complete isotp frames. So for reception that is not complete, an isotp first frame is discarded if overridden as needed from the queue, and never fired to the user.

    basically if you send a VIN request using Can0.write(msg) normal frame, yes you need to send a flow frame. The library just rebuilds the ECU frames it doesnt do the requests. if you dont send the flow control the first frame sits in queue to do nothing, or be overridden as queue space permits

    for teensy to teensy or teensy to esp32, they send the complete payload based on the example format, and since the payload is complete, after the rebuild is successful the user callback is fired with it

    so yes for the ecu you need to send the flow control, teensy just captures full payloads, and rebuilds and fire as needed

    the isotp data in the example is the flow control just for the payload teensy is sending to send at those specific rates

  5. #1055
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    isotp server acts same way like ecu

  6. #1056
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    So perhaps I could register a regular callback to check if the frame starts with 0x10, then send a flow control,
    And I would receive the full payload in the isotp callback? Would that be possible?

  7. #1057
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    yes that will work, you could also just send it 10ms after the request

  8. #1058
    Junior Member
    Join Date
    Sep 2022
    Posts
    1
    Hi,

    I have a question on the ACK between 2 Teensy 4.1's
    My setup has one Teensy transmitting and the other receiving, which is working.
    But, I don't want the transmitting Teensy to be interruped in case of an ACK fail, and having to retransmit the message.

    I haven't found the option in the library to disable an automatic retransmission yet.
    Does this option exist, or is there another possible solution to not get any interruption on the transmitting Teensy?

  9. #1059
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    the hardware retransmits automatically, even if you call an abort on the mailbox it may or may not transmit a garbage frame, and if your code is retransmitting over a loop you'll just be enabling it to transmit until it acks until the abort command is issued. if there is no ACK on the network it'll just keep retransmitting, it wont block your code. once an ACK is issued the next frame can be written to the mailbox, until then other writes to a transmit box that is waiting for ACK is discarded. Even though there is a transmit once feature (which we DO actually use), the hardware will ALWAYS send endlessly until that ONE frame is successfully sent.

  10. #1060
    Junior Member
    Join Date
    May 2018
    Posts
    19
    I have a question on the sample CAN2.0_example_FIFO_with_interrupts.ino

    In the code, it appears to be making random transmits onto the CAN bus. What is the purpose of this? If one was on CAN bus, shouldn't 0x7DF be the message ID from a test scanner tool to instruct modules to report PIDs? I understand CAN has many applications but my question is specific to vehicle CAN bus applications.


    if ( millis() - timeout > 200 ) {
    CAN_message_t msg;
    msg.id = random(0x1,0x7FE);
    for ( uint8_t i = 0; i < 8; i++ ) msg.buf[i] = i + 1;
    Can0.write(msg);
    timeout = millis();
    }

  11. #1061
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    this is just an example of sending and receiving, you can change it up to your purpose as needed

  12. #1062
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    Quote Originally Posted by tonton81 View Post
    yes that will work, you could also just send it 10ms after the request
    hi Tony,

    I created this example:
    Code:
    #include <FlexCAN_T4.h>
    #include <isotp.h>
    isotp<RX_BANKS_16, 512> tp; /* 16 slots for multi-ID support, at 512bytes buffer each payload rebuild */
    
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can1;
    
    void myCallback(const ISOTP_data &config, const uint8_t *buf) {
      Serial.print("ID: ");
      Serial.print(config.id, HEX);
      Serial.print("\tLEN: ");
      Serial.print(config.len);
      Serial.print("\tFINAL ARRAY: ");
      for ( int i = 0; i < config.len; i++ ) {
        Serial.print(buf[i], HEX);
        Serial.print(" ");
      } Serial.println();
    }
    
    void canSniff(const CAN_message_t &msg) {
     uint8_t flowControl[] = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     if (msg.buf[0] == 0x10){
        ISOTP_data configFlowCont;
        configFlowCont.id = 0x17FC0076;
        configFlowCont.flags.extended = 1; /* standard frame */
        configFlowCont.separation_time = 0; /* time between back-to-back frames in millisec */
        tp.write(configFlowCont, flowControl, sizeof(flowControl));
      }
    }
    
    void setup() {
      Serial.begin(115200); delay(400);
      Can1.begin();
      Can1.setClock(CLK_60MHz);
      Can1.setBaudRate(500000);
      Can1.setMaxMB(16);
      Can1.enableFIFO();
      Can1.enableFIFOInterrupt();
      Can1.onReceive(canSniff);
      tp.begin();
      tp.setWriteBus(&Can1); /* we write to this bus */
      tp.onReceive(myCallback); /* set callback */
    }
    
    void loop() {
      static uint32_t sendTimer = millis();
      if ( millis() - sendTimer > 1000 ) {
        CAN_message_t msg;
        uint8_t buf[] = {0x07, 0x22, 0xF4, 0x33, 0xF4, 0x0F, 0xF4, 0x3C};
        ISOTP_data config;
        config.id = 0x17FC0076;
        config.flags.extended = 1; /* standard frame */
        config.separation_time = 0; /* time between back-to-back frames in millisec */
        tp.write(config, buf, sizeof(buf));
        //memcpy(msg.buf, buf, sizeof(msg.buf)); // Copy the data array into the message buffer
        //msg.len = 8;
        //msg.flags.extended = 1; // 29 bit header
        //msg.id = 0x17FC0076; // request header for OBD
        //Can1.write(msg);
        sendTimer = millis();
      }
    }
    But what I see the library is transmit the following which :
    Code:
    0x10, 0x08, 0x07, 0x22, 0xF4, 0x33, 0xF4
    0x21, 0xF4, 0x3C, 0x00, 0xF4, 0x33, 0xF4
    where is should just transmit:
    Code:
    0x07, 0x22, 0xF4, 0x33, 0xF4, 0x0F, 0xF4, 0x3C
    What could be the cause of this?
    I tried to transmit with Can1 but then istop does not catch anything coming in.

  13. #1063
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    effectively that writes the 8 bytes as a payload in isotp format (2 frames for payload)

    so, 8 bytes as payload plus isotp header
    to send that just as a frame itself use Can1.write(msg)
    Last edited by tonton81; 09-05-2022 at 02:44 PM.

  14. #1064
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    As I mentioned in the last line of my previous post, I transmitted with Can1.write(msg) but then istop did not catch the payload - so the istop callback is never triggered.

  15. #1065
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    you need to send that frame, then send the flow control after, if you don't send the flow control frame the ecu will not send out the full isotp frame, and if the full isotp frame is not sent out you wont get a callback because it hasn't been assembled since the ecu didn't send the consecutive frames

  16. #1066
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    But I do send out my flow control frame, using the canSniff callback in my example.
    Per ISOTP, the flow control should be sent after the first frame is received, and not after the request frame has been sent as you suggest.
    Perhaps I should also transmit from Can1.write in the canSniff callback and then it might work..

  17. #1067
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    yes send both as normal frames, the isotp is there just to assemble messages in stream

  18. #1068
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    Quote Originally Posted by tonton81 View Post
    yes send both as normal frames, the isotp is there just to assemble messages in stream
    Great, this is exactly the behavior I would like.

    I modified the sketch, will test it tomorrow.
    Code:
    #include <FlexCAN_T4.h>
    #include <isotp.h>
    isotp<RX_BANKS_16, 512> tp; /* 16 slots for multi-ID support, at 512bytes buffer each payload rebuild */
    
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can1;
    
    void myCallback(const ISOTP_data &config, const uint8_t *buf) {
      Serial.print("ID: ");
      Serial.print(config.id, HEX);
      Serial.print("\tLEN: ");
      Serial.print(config.len);
      Serial.print("\tFINAL ARRAY: ");
      for ( int i = 0; i < config.len; i++ ) {
        Serial.print(buf[i], HEX);
        Serial.print(" ");
      } Serial.println();
    }
    
    void canSniff(const CAN_message_t &msg) {
     uint8_t flowControl[] = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     if (msg.buf[0] == 0x10){
        memcpy(msg.buf, flowControl, sizeof(msg.buf));
        msg.len = 8;
        msg.flags.extended = 1; 
        msg.id = 0x17FC0076; 
        Can1.write(msg);
      }
    }
    
    void setup() {
      Serial.begin(115200); delay(400);
      Can1.begin();
      Can1.setClock(CLK_60MHz);
      Can1.setBaudRate(500000);
      Can1.setMaxMB(16);
      Can1.enableFIFO();
      Can1.enableFIFOInterrupt();
      Can1.onReceive(canSniff);
      tp.begin();
      tp.setWriteBus(&Can1); /* we write to this bus */
      tp.onReceive(myCallback); /* set callback */
    }
    
    void loop() {
      static uint32_t sendTimer = millis();
      if ( millis() - sendTimer > 1000 ) {
        CAN_message_t msg;
        uint8_t buf[] = {0x07, 0x22, 0xF4, 0x33, 0xF4, 0x0F, 0xF4, 0x3C };
        memcpy(msg.buf, buf, sizeof(msg.buf));
        msg.len = 8;
        msg.flags.extended = 1;
        msg.id = 0x17FC0076; 
        Can1.write(msg);
        sendTimer = millis();
      }
    }

  19. #1069
    Senior Member
    Join Date
    Oct 2019
    Posts
    355
    So my test sketch worked, thanks Tony!
    I do have two more questions:
    1. If the response payload is 8 bytes (single frame) will the isotp callback still trigger?
    2. In the isto constructor the comment says “16 slots for multi-ID support” - what does this mean? Is it a filter? How can I define the IDs?

  20. #1070
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,078
    1) it should provided the payload is 6 bytes or less, provided the first 2 bytes are passes as an isotp header. if you prefer not receiving those single frames whivh can exist during debugging, i usually just filter them out when the size is less than 6

    2) 16 slots aka queues, each entry stores a unique canid, for rebuilding. so up to 16 canids can be assembled at same time. you don't define the IDs, isotp frames are assigned a slot automatically for rebuilding, if all slots are full the queue just rolls over the older slot. i doubt you'll be using 16 reassemblies at same time though

    there are no filters for the plugin. as long as one or more mailboxes/fifo sees an isotp frame, it will attempt re-assembly of payload on it. if you apply filters to mailboxes/fifo, then it cant assemble data it wont see, it's just a non-invasive passive type of plugin i guess

  21. #1071
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    512
    Tony (@tonton81):

    I would like to express my deep appreciation & gratitude for the FlexCAN_t4 library (I believe) that you have contributed. By utilizing that excellent capability, I have been able to create a CAN/isotp monitor that is able to send service requests & to properly process/parse the returning responses. As I have slowly been adding capabilities, I have been posting updates to my sketch in <another thread>, as well as example captures (also in <that thread>) from what I have been able to decode from monitoring the CAN bus pins of the OBD-II connector on my 2020 Honda Civic as I send out the supported service requests & process/parse the returning responses.

    Thanks again for your expertise & contributions !!

    Mark J Culross
    KD5RXT

  22. #1072
    Junior Member
    Join Date
    Jan 2022
    Posts
    9

    Question Sanity Check for Simple CAN Circuit

    Hi All,

    I had been working on a project a few months back and it ended up falling by the wayside, trying to pick it back up now and wanted to start out by validating a super simple communication circuit between two Teensy 4.0s. I'm running into repeated issues that are throwing me off, my next step is buying new hardware in case I have a bad CAN transceiver specifically, but figured I would come over this way for a sanity check on everything else before buying new stuff.

    I've got two Teensy 4.0s, both wired through the CRX1 and CTX1 pins, configured to use CAN1 based off the CAN2.0_example_FIFO_with_interrupts example code. I've tested all of this at both 1,000,000 and 100,000 baudrates. I've modified one teensy to transmit with the ID 0x123 and the other with ID 0x456, with identical data packets. By sniffing the RX and TX lines between each Teensy and Transceiver, I am reliably seeing the message sending, but it does not appear to be transmitting across the bus between Teensies. I'm getting a NAK response according to the packet analyzer, with an example packet output being seen below.

    ID: 456 DLC: 08 Data: 01 02 03 04 05 06 07 08 CRC: 274A NAK

    I believe this means that the communication between both transceivers is failing and had a spare SN65HVD230 based chip that I tried to use to eliminate a single broken transceiver, but I only have the one, so if a transceiver is broken, it would seem both are. I figure this to be somewhat unlikely but I'm kind of grasping at straws. For the circuit, the transceivers each have the following pins:

    3V3: Tied to its Teensy's 3V3
    GND: Tied to its Teensy's GND
    RX: Tied to its Teensy's CRX1
    TX: Tied to its Teensy's CTX1
    CANH: Tied to the other transceiver's CANH
    CANL: Tied to the other transceiver's CANL

    I can include the code if necessary, but it is literally the example mentioned above, but with the ID swapped out to differentiate.

    I half feel like I'm just missing something I should know, but otherwise I might just need to get some new transceivers. Any advice would be greatly appreciated.

    Quick Edit:
    Wanted to mention I've checked all wires for continuity, checked voltages at the transceivers, everything looks good there. I'm going to check for a short at the CANH / CANL resistor in a moment, as it is built into the chip I'm using but don't have my hands on my multimeter at the moment. I've also been able to verify setup execution by seeing the mailboxStatus() function execution output, as well as testing for the write() function execution from using Serial output, along with being able to see the transmitted messages on the teensy pin nodes.
    Last edited by oVexlz; 10-04-2022 at 10:42 PM. Reason: Additional Detail

  23. #1073
    Junior Member
    Join Date
    Oct 2022
    Posts
    3

    CAN extended frames seems to not be sent

    Hi all,

    I'm having trouble sending a CAN frame with an 29 bits extended ID on a Teensy 4.1.

    I'm trying to communicate with an actuator (A CubeMars AK60) which uses both extended and standard ID frames for different modes of operation.

    I successfully sent many standard frames and the actuator did what it was supposed to do. I'm now trying to use another mode of the actuator which requires an Extended ID frame and I've had no luck with that.

    Here's a sample of the code where method run is called each 4 seconds with changed values:
    Code:
    void AK60_init()
    {
        can1.begin();
        can1.setBaudRate(1000000);
    }
    
    void run()
    {
        //buffer is a byte array containing the data to send
        send_std_can_message(buffer, Position_Velocity);
        can1.mailboxStatus();
    }
    
    void send_std_can_message(byte buff[], Mode mode = None)
    {
        CAN_message_t msg;
        uint32_t id = TEENSY_CAN_ID;
        bool extended = 0;
    
        for (uint8_t i=0; i<8; i++){
            msg.buf[i] = buff[i];
        }
    
        if (mode != None)
        {
            id = TEENSY_CAN_ID | (mode << 8);
            extended = 1;
        }
    
        msg.flags.extended = extended;
        msg.id = id;
        msg.len = 8;
    
        can1.write(msg);
    }
    The AK60 is a bit tricky, it requires the mode type to be mixed with the ID of the Teensy. I've validated each data sent and they're all well packaged, so that wouldn't be the issue. I've also tried using the filters, but I'm not very familiar with them and assumed it wasn't the issue. The current setup uses the default Mailboxes, but they seem to receive no data after the can1.write(msg) method has been called. Does someone know what could be causing the problem here?

    Thanks!

  24. #1074
    Unless I'm missing something, it seems like your code is calling the send_std_can_message function as fast as the teensy can loop. This is certainly faster than a 1Mbps bus can transmit those frames, causing the teensy to flood the bus. Try putting your function in a timing conditional like:
    Code:
    if ( millis() - timeout > 200 ) {
       send_std_can_message(buffer, Position_Velocity);
       can1.mailboxStatus();
       timeout = millis();
    }
    Last edited by msadie; 10-06-2022 at 03:19 AM. Reason: Fix code

  25. #1075
    Junior Member
    Join Date
    Oct 2022
    Posts
    3
    Thanks for the response!

    It could be a problem, but in my case, the method run() is called with a delay of 4 seconds each time, which is far more than enough for the CAN transmission.
    Any other ideas?

Posting Permissions

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