Forum Rule: Always post complete source code & details to reproduce any issue!
Page 25 of 27 FirstFirst ... 15 23 24 25 26 27 LastLast
Results 601 to 625 of 673

Thread: FlexCAN_T4 - FlexCAN for Teensy 4

  1. #601
    Junior Member
    Join Date
    Mar 2021
    Posts
    2
    Quote Originally Posted by tonton81 View Post
    I *think* you wan't to pass an object, but in templates the objects are not easily passable to functions. However, thats why a base class exists so FlexCAN_T4 can also do it's tasks in background giving you the ability to have your own named object, without the extra loss of resources and pins of controllers you don't need initialized. Anyways, you need to make a pointer of FlexCAN_T4_Base* class. You may pass them to your functions as long as you are using the FlexCAN_T4_Base class reference and not FlexCAN_T4 class directly.

    Check out the isotp source included in FlexCAN_T4, it will show you how it uses the base class to read and write the bus as a plugin library

    Examples:
    Pointer creation:
    Code:
    static FlexCAN_T4_Base* _isotp_busToWrite = nullptr;
    Set the pointer: (tp.setWriteBus(&Can1), function here shows passing a pointer from your template object, like "can1")
    Code:
        void setWriteBus(FlexCAN_T4_Base* _busWritePtr) { _isotp_busToWrite = _busWritePtr; }
    Use the pointer:
    Code:
    _isotp_busToWrite->write(msg);
    Thank you very much for the quick reply @tonton81! I will try your suggestions this weekend and report back to you afterwards!

  2. #602
    Junior Member
    Join Date
    Mar 2021
    Posts
    15
    Quote Originally Posted by MarkT View Post
    I can't see a reference design - the datasheet does explain about noise-reducing components on the digital signals,
    but you seem to have used 100nF for a noise-reducing capacitor value which is far too large. 33pF, 100pF, that
    sort of value is appropriate. Only the decoupling capacitor(s) should be 100nF (C4 in your circuit). C5 and C6
    are on a logic line, not a supply, so you don't decouple them.
    oh, yeah. that could explain it. i just got a sample book in so i'll try 33pF. C6 was chosen fairly large as it shouldn't be switched during normal opperation, should i use a smaller cap there?

    Edit: placed the 10k back and a C5 as an 33pF cap and it works!!!!!
    Last edited by RayanR; 04-02-2021 at 08:06 AM.

  3. #603
    Senior Member
    Join Date
    Jun 2014
    Posts
    251
    @tonton81 Mind if I send you a TCAN330 board? I created a non-FD board and am having trouble getting it to work, unsure why. I read in this thread that I'm not alone.

  4. #604
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,701
    make sure you have the chip set to normal mode, theres pins that have pullups and pulldowns on that IC and if it's not in normal mode it won't work, @msadie has the same chip as you and claims it works

    what does your sketch and physical pins look like?

  5. #605
    As @tonton81 mentioned, I've had success with both the TCAN330 and TCAN337. Aside from the special function pins and being powered by 3.3V, these transceivers function the as well as any others I've used with teensy 4/4.1.

  6. #606
    Senior Member
    Join Date
    Jun 2014
    Posts
    251
    I wasn't expecting any problems. I have long-term experience with the SN65HVD230D chips and they're flawless.
    Here's my setup. This is a custom PCB I made, which has dual TCAN330's. There are pins to pull SHDN/SILENT modes high or low (Teensy pins 2, 3).
    The board has a jumper pad that should be cut to either control SHDN or S. I have not cut the trace, thinking I can just pull both low at the same time (maybe this is the mistake?).
    I am using one of the examples sketches, just adding the pullup/down:

    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;
    
    const int sleepPin1 = 2;
    const int sleepPin2 = 3;
    
    void setup(void) {
      pinMode(sleepPin1, OUTPUT);
      pinMode(sleepPin2, OUTPUT);
      digitalWrite(sleepPin1, LOW);
      digitalWrite(sleepPin2, HIGH);
      
      can1.begin();
      can1.setBaudRate(250000);
      can2.begin();
      can2.setBaudRate(250000);
    }
    
    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);
      }
      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);
      }
    }
    I am connecting to an 11B/250K CAN simulator. This is known working, tested with a different device.
    I'm using CAN2 (pins 0, 1), pulling the appropriate function pin low (sleepPin1), but not getting anything at all from the Teensy. I have also tried removing the 120ohm resistor.
    sleepPin2 is high to disable CAN1 (22, 23). I have a common ground with the simulator.
    Any ideas are greatly appreciated.

    Click image for larger version. 

Name:	IMG_2699.jpg 
Views:	23 
Size:	221.0 KB 
ID:	24320

  7. #607
    Do you have an oscilloscope or logic analyzer that you can use to verify signals? Viewing CANH/CANL and TX/RX signals would make quick work of troubleshooting.

  8. #608
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,701
    check mailboxStatus(), if all of your TX mailboxes fill up, you have a bad physical connection, miswire, termination issue, worse case scenario, bad transceiver

  9. #609
    Senior Member
    Join Date
    Aug 2014
    Posts
    172
    Does anyone have a working recipe for interfacing a Teensy 4.0 with a Megasquirt?

    I'm having issues with a SN65HVD230 and my MS3. I'm not getting anything back.

  10. #610
    Senior Member
    Join Date
    Jun 2014
    Posts
    251
    Quote Originally Posted by msadie View Post
    Do you have an oscilloscope or logic analyzer that you can use to verify signals? Viewing CANH/CANL and TX/RX signals would make quick work of troubleshooting.
    Unfortunately not. All I can say is that I'm measuring 2.05ish volts on the L and H pins.

  11. #611
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,701
    voltage seems about right, are the pins maybe reversed?

  12. #612
    Senior Member
    Join Date
    Jun 2014
    Posts
    251
    First loop

    Code:
    FIFO Disabled
    	Mailboxes:
    		MB0 code: RX_EMPTY	(Standard Frame)
    		MB1 code: RX_EMPTY	(Standard Frame)
    		MB2 code: RX_EMPTY	(Standard Frame)
    		MB3 code: RX_EMPTY	(Standard Frame)
    		MB4 code: RX_EMPTY	(Extended Frame)
    		MB5 code: RX_EMPTY	(Extended Frame)
    		MB6 code: RX_EMPTY	(Extended Frame)
    		MB7 code: RX_EMPTY	(Extended Frame)
    		MB8 code: TX_INACTIVE
    		MB9 code: TX_INACTIVE
    		MB10 code: TX_INACTIVE
    		MB11 code: TX_INACTIVE
    		MB12 code: TX_INACTIVE
    		MB13 code: TX_INACTIVE
    		MB14 code: TX_INACTIVE
    		MB15 code: TX_INACTIVE
    Second loop

    Code:
    FIFO Disabled
    	Mailboxes:
    		MB0 code: RX_FULL
    		MB1 code: RX_FULL
    		MB2 code: RX_FULL
    		MB3 code: RX_OVERRUN
    		MB4 code: RX_EMPTY	(Extended Frame)
    		MB5 code: RX_EMPTY	(Extended Frame)
    		MB6 code: RX_EMPTY	(Extended Frame)
    		MB7 code: RX_EMPTY	(Extended Frame)
    		MB8 code: TX_INACTIVE
    		MB9 code: TX_INACTIVE
    		MB10 code: TX_INACTIVE
    		MB11 code: TX_INACTIVE
    		MB12 code: TX_INACTIVE
    		MB13 code: TX_INACTIVE
    		MB14 code: TX_INACTIVE
    		MB15 code: TX_INACTIVE
    Edit:
    Used this code from post #75 (just different enable pin) and everything seems fine.

    Code:
    #include <FlexCAN_T4.h>
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can0;
    
    void setup(void) {
      Serial.begin(115200); delay(400);
      pinMode(2, OUTPUT); digitalWrite(2, LOW); // enable tranceiver
      Can0.begin();
      Can0.setBaudRate(500000);
      Can0.setMaxMB(16); // up to 64 max for T4, not important in FIFO mode, unless you want to use additional mailboxes with FIFO
      Can0.enableFIFO();
      Can0.enableFIFOInterrupt();
      Can0.onReceive(canSniff);
      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();
    
      static uint32_t timeout = millis();
      if ( millis() - timeout > 20 ) { // send random frame every 20ms
        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();
      }
    
    }
    Output

    Code:
    FIFO Enabled --> Interrupt Enabled
    	FIFO Filters in use: 8
    	Remaining Mailboxes: 8
    		MB8 code: TX_INACTIVE
    		MB9 code: TX_INACTIVE
    		MB10 code: TX_INACTIVE
    		MB11 code: TX_INACTIVE
    		MB12 code: TX_INACTIVE
    		MB13 code: TX_INACTIVE
    		MB14 code: TX_INACTIVE
    		MB15 code: TX_INACTIVE
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 40290 ID: 7E8 Buffer: 3 7F 2 31 55 55 55 55 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 34684 ID: 7E8 Buffer: 3 7F 2 31 55 55 55 55 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 44981 ID: 7DF Buffer: 2 1 0 0 0 0 0 0 
    MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 55476 ID: 7E8 Buffer: 6 41 0 FF FF FF FF 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 40179 ID: 7DF Buffer: 2 1 0 0 0 0 0 0 
    MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 49934 ID: 7E8 Buffer: 6 41 0 FF FF FF FF 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 13198 ID: 7DF Buffer: 2 1 0 0 0 0 0 0 
    MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 23311 ID: 7E8 Buffer: 6 41 0 FF FF FF FF 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 34185 ID: 7DF Buffer: 2 1 20 0 0 0 0 0 
    MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 45268 ID: 7E8 Buffer: 6 41 20 FF FF FF FF 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 50372 ID: 7DF Buffer: 2 1 40 0 0 0 0 0 
    MB 99  OVERRUN: 0  LEN: 7 EXT: 0 TS: 62225 ID: 7E8 Buffer: 6 41 40 FF FF FF FE 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 42899 ID: 7DF Buffer: 2 9 A 0 0 0 0 0 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 54184 ID: 7E8 Buffer: 10 17 49 A 1 45 43 4D 
    MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 54317 ID: 7E0 Buffer: 30 0 0 0 0 0 0 0
    Last edited by Fyod; 04-07-2021 at 08:42 PM.

  13. #613
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,701
    oh good you got it working

  14. #614
    Senior Member
    Join Date
    Jun 2014
    Posts
    251
    While browsing this thread I have seen someone working with MS.
    https://forum.pjrc.com/threads/56035...irt#post231492

  15. #615
    Senior Member
    Join Date
    Aug 2014
    Posts
    172
    Quote Originally Posted by RayanR View Post
    oh, yeah. that could explain it. i just got a sample book in so i'll try 33pF. C6 was chosen fairly large as it shouldn't be switched during normal opperation, should i use a smaller cap there?

    Edit: placed the 10k back and a C5 as an 33pF cap and it works!!!!!
    @RayanR — could you draw up your final schematic? Would be super useful.

  16. #616
    Senior Member
    Join Date
    Aug 2014
    Posts
    172
    Quote Originally Posted by Fyod View Post
    While browsing this thread I have seen someone working with MS.
    https://forum.pjrc.com/threads/56035...irt#post231492
    Thanks! Somehow missed this.

  17. #617
    Senior Member
    Join Date
    Aug 2014
    Posts
    172
    Got a fresh bare SN65HVD230 working. 10k from RS to ground, 100R across CANH and CANL. That was all. Seems that the breakout board I originally bought was duff.

    Tempted to try out the TN330/332 as that seems newer and... probably better? Also saves me a 10k resistor by the looks of it.

    I have a question regards mailboxes and what's the real use case for them.

    MegaSquirt spits out data - e.g byte 2 and 3 from ID 1520 is RPM - for instance. IDs have multiple pieces of information. What's the most efficient way of processing this?

    I presume I setup mailboxes filtered or each ID that I want to capture, and then in the interrupt routine I then parse the frame into my programs variables?

    The other option would be to just keep a cache of can messages in an array - 1520 -> [0], 1521 -> [1] etc - and only process them when I need them (I don't need all of the variables all of the time, I only need them when I want to display them)

  18. #618
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,701
    mailboxes are like a drop box queue, each one can hold one receive (or transmit) message, the others wait in line to grab the next one. FIFO (rx only) is 6 messages deep, in reception order. Mailboxes can receive frames in any order. You can set multiple filters on FIFO, mailboxes have only one filter.

  19. #619
    Quote Originally Posted by jcarruthers View Post
    Got a fresh bare SN65HVD230 working. 10k from RS to ground, 100R across CANH and CANL. That was all. Seems that the breakout board I originally bought was duff.

    Tempted to try out the TN330/332 as that seems newer and... probably better? Also saves me a 10k resistor by the looks of it.

    I have a question regards mailboxes and what's the real use case for them.

    MegaSquirt spits out data - e.g byte 2 and 3 from ID 1520 is RPM - for instance. IDs have multiple pieces of information. What's the most efficient way of processing this?

    I presume I setup mailboxes filtered or each ID that I want to capture, and then in the interrupt routine I then parse the frame into my programs variables?

    The other option would be to just keep a cache of can messages in an array - 1520 -> [0], 1521 -> [1] etc - and only process them when I need them (I don't need all of the variables all of the time, I only need them when I want to display them)
    If you have a limited enough set of rx IDs, I find it easiest to just assign each its own mailbox using the mailbox filters. Unless you are logging data or receiving multi-frame data packets, you generally only concerned with the most recent data. In this case, you want to service the mailbox rx fast enough to avoid queueing the incoming frames. This can be achieved by interrupt or polling, with the selection being based on your receive rates and other cpu load.

  20. #620
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,701
    also if a mailbox gets a similar frame in other than it's own in filter mode, an overrun would occur and the frame would be overwritten. example without filters is, if all the mailboxes fill up without reading them, only the last mailbox to accept the frame is overwritten always with latest data. This is a hardware feature and not controlled by software. Technically if you block all IDs and assign only one mailbox to filter your ECU ID, that mailbox will always keep the latest frame as it keeps rewriting it over and over and over, so if ECU sends 3 frames, and if you read it, you'll see the 3rd only. If you are not using interrupts it's something to think about, useful or not, but with interrupts, you won't get overruns

  21. #621
    Senior Member
    Join Date
    Aug 2014
    Posts
    172
    Thanks, @tonton81 and @msadie

    If I'm using interrupts... and can.events() in loop() —*will it process all the frames in one go? or does it rely on the loop to iterate through them?

    I'd like to add an update flag to the interrupt — so that the display only bothers to update when there is new data.

  22. #622
    No need to use can.events() if you are using mailbox interrupts. The interrupt will fire upon receipt of each message, and the received message object will be passed as an input arg. You can use one interrupt function for all MBs, check it's ID and process it accordingly. Or you can have different functions attached to different MBs based on their ID filters.

  23. #623
    Regarding adding the 'new data' flag, that's a good idea. If your msg unpacking routine is intensive, you might just copy your message from the interrupt to a global, set a 'new msg 1501' flag, then later unpack it in loop().

  24. #624
    Senior Member
    Join Date
    Aug 2014
    Posts
    172
    Quote Originally Posted by msadie View Post
    Regarding adding the 'new data' flag, that's a good idea. If your msg unpacking routine is intensive, you might just copy your message from the interrupt to a global, set a 'new msg 1501' flag, then later unpack it in loop().
    Hmmm — I was using FIFO.

    If the mailbox has more than one frame in it —*how can I ensure that they are all dealt with in one go? or is that not possible?

    I'm using MegaCAN which has quite a hefty parsing 450 line switch statement with 63 cases; https://github.com/mantonakakis1/Meg...er/MegaCAN.cpp

    In truth I probably don't need to process the frames as soon as they arrive. Once I've rendered the gauges etc there's no rush until the next loop.

    This is what I have currently:

    Code:
    void setup() {
      Serial.begin(115200);
    
      can.begin();
      can.setBaudRate(500000);
      can.enableFIFO();
      can.enableFIFOInterrupt();
      can.onReceive(decodeCAN);
    
    }
    
    void loop() {
    
      if (update) {
    
        update = false;
    
        Serial.println(ms.rpm);
    
      }
    
    }
    
    void decodeCAN(const CAN_message_t &msg) {
    
      MSCAN.getBCastData(msg.id, msg.buf, ms);
    
      update = true;
    
    }
    Last edited by jcarruthers; 04-10-2021 at 04:36 PM.

  25. #625
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,701
    mailbox holds one frame only, FIFO holds 6

Posting Permissions

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