Forum Rule: Always post complete source code & details to reproduce any issue!
Page 14 of 17 FirstFirst ... 4 12 13 14 15 16 ... LastLast
Results 326 to 350 of 421

Thread: FlexCAN_T4 - FlexCAN for Teensy 4

  1. #326
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    I havn't messed with CANopen so at the moment I couldn't give you an answer. If there is a library that uses it and it's working on teensy (most likely with old flexcan library), I may try to port it over. IFCT allowed alot of old flexcan library emulation for Teensy 3.2-3.6, but not adapted to T4 yet. Do you have an official link to teensy version of CANopen I could look at?

  2. #327
    Junior Member
    Join Date
    Jul 2020
    Posts
    2
    Hello and thank you for the reply.

    Its my opinion that it will be many years until someone with the time and the skills will be able to claim the Full CANopen stack crown for a free library!
    But i do know people have got various bits of the protocol working, so they can run CANopen devices but you can't call it a full blown stack implementation to the standards.

    I would hope someone can back me up or put me straight on this, but i believe a very low overhead implementation will open up these CANopen devices and allow most of the functionality to be accessible, but with more work on the user end to send the can frames.

    The Basic requirement would be :-

    1) the NMT..... you will see references to this in the other library's (network management / state machine to deal with the process of passing into various stages of "On" / "off" / "standby" to put it simply, this relates to the CAN messages in my first post) but the NMT send out a heartbeat that bust be managed by the NMT.

    2) POD transmit and receive.... so again if you can send messages in a frame you can turn a drive into a position or velocity mode for example then send it a value to run at.


    https://github.com/jgeisler0303/CANFestivino
    This is the only link that i believe comes close to running on Arduino....but it was for using the MCP2515 or the "Seeed CAN bus shield"


    I did spend some / alot of time with a linux canopen library https://github.com/christiansandberg/canopen
    this worked very well and full featured but was for python, and used on a beagelbone black single board computer....... so not sure if this is even useful ? but very well documented.


    I hope this is useful information, and thank you for considering this.

  3. #328
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    the old flexcan library or the MCP library could be emulated with a dummy class that will forward their controls over to the latest flexcan driver. i dodn't say i'd write a canopen stack thats an entire new project on it's own, but if the library uses mcp2515 library then we only need to mimic the mcp2515 library with a dummy class to get right control over the new driver, we did emulation work in IFCT, but felt it kinda bloated the driver class, so a separate library with the dummy classes would be a suggested route to goto but best to find a well known and used canopen stack on arduino platform before we start diving into new classes

  4. #329
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    I saw pgchui attempt to do this and was having some issues with cansniff. I'm just trying to verify if my transceivers work. I'm using a teensy 4.1 using can1 and can 2 with SN65HVD230 to make sure they work since SN65HVD230 seem to have issues sometimes.

    I'm not seeing anything printing on the serial monitor, I figured I would see something regardless if it is garbage or not.




    Code:
    #include "Arduino.h"
    #include "FlexCAN_T4.h"
    
    FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
    
    void canSniff(const CAN_message_t &msg);
    
    void setup() {
        Serial.begin(9600);
        can1.begin();
        can2.begin();
        can1.setBaudRate(1000000);
        can2.setBaudRate(1000000);
        can1.enableFIFO();
        can1.enableMBInterrupt(FIFO);
        can1.onReceive(FIFO, canSniff);
        can2.enableFIFO();
        can2.enableMBInterrupt(FIFO);
        can2.onReceive(FIFO, canSniff);
        delay(1000);
        Serial.println("CAN setup finished");
    }
    
    void loop() {
        can1.events();
        can2.events();
        if (Serial.available()) {
            char c = Serial.read();
            if (c == 'a') {
                Serial.println("Sending ...");
                CAN_message_t msg;
                msg.len = 8;
                msg.id = 0x321;
                msg.buf[0] = 1;
                msg.buf[1] = 2;
                msg.buf[2] = 3;
                msg.buf[3] = 4;
                msg.buf[4] = 5;
                msg.buf[5] = 6;
                msg.buf[6] = 7;
                msg.buf[7] = 8;
    
                can1.write(msg);
    
    //            delay(100);
    //            can2.read(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();
            }
        }
        delay(100);
    }
    
    void canSniff(const CAN_message_t &msg) {
        Serial.println("Interrupted");
        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();
    }

  5. #330
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    are you looping the busses? do you have termination?

  6. #331
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    Quote Originally Posted by tonton81 View Post
    are you looping the busses? do you have termination?
    I'm not sure what you mean by looping. The transceivers are both terminated, I didn't remove them since I know the bus has to be terminated on both ends..

    Click image for larger version. 

Name:	IMG_20200731_005125.jpg 
Views:	24 
Size:	112.5 KB 
ID:	21215
    Click image for larger version. 

Name:	IMG_20200731_005118.jpg 
Views:	25 
Size:	101.5 KB 
ID:	21216

    here is a picture of the setup

  7. #332
    Change enableMBInterrupt(FIFO) to enableFIFOInterrupt() for both CAN channels. I think you may have found a bug (or at least an issue with the readme, which suggests this exact code).

    Also, events() isn't needed if you have the latest version of FlexCAN_T4 library from https://github.com/tonton81/FlexCAN_T4/

    @tonton81: I think enableMBInterrupt(FIFO) tries to writeIMASKBit(99), which is out of range.

  8. #333
    Ive confirmed this behavior on CAN1/CAN2 of a T4.0
    Arduino 1.8.13 / Teensyduino 1.53

  9. #334
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    Still no dice, I changed per msadie's suggestion:

    Code:
    #include "Arduino.h"
    #include "FlexCAN_T4.h"
    
    FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
    
    void canSniff(const CAN_message_t &msg);
    
    void setup() {
        Serial.begin(9600);
        can1.begin();
        can2.begin();
        can1.setBaudRate(1000000);
        can2.setBaudRate(1000000);
        can1.enableFIFO();
        can1.enableFIFOInterrupt();
        can1.onReceive(FIFO, canSniff);
        can2.enableFIFO();
        can2.enableFIFOInterrupt();
        can2.onReceive(FIFO, canSniff);
        delay(1000);
        Serial.println("CAN setup finished");
    }
    
    void loop() {
        if (Serial.available()) {
            char c = Serial.read();
            if (c == 'a') {
                Serial.println("Sending ...");
                CAN_message_t msg;
                msg.len = 8;
                msg.id = 0x321;
                msg.buf[0] = 1;
                msg.buf[1] = 2;
                msg.buf[2] = 3;
                msg.buf[3] = 4;
                msg.buf[4] = 5;
                msg.buf[5] = 6;
                msg.buf[6] = 7;
                msg.buf[7] = 8;
    
                can1.write(msg);
    
    //            delay(100);
    //            can2.read(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();
            }
        }
        delay(100);
    }
    
    void canSniff(const CAN_message_t &msg) {
        Serial.println("Interrupted");
        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();
    }
    Click image for larger version. 

Name:	EmptySerialMonitor.PNG 
Views:	12 
Size:	137.9 KB 
ID:	21217

    Click image for larger version. 

Name:	TeensySettings.jpg 
Views:	15 
Size:	91.3 KB 
ID:	21218

  10. #335
    Can you select Tools -> Port -> COM3 Serial (Teensy 4.1) and try again?

  11. #336
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    It did a thing!

    Click image for larger version. 

Name:	ItDidaThing.PNG 
Views:	28 
Size:	18.9 KB 
ID:	21219

    I'm not sure why it doesn't continue to update, and I also lost the ability to select the baud rate. Do you think because Serial.begin() is in the setup() and not loop() would cause this?

  12. #337
    Serial.begin() belongs in setup().

    Per your code, it will only display more if you type "a" in the line at the top of the serial monitor and hit Send.

  13. #338
    Check out this post for a succinct explanation on why that baud rate is gone (and most often is ignored).

    https://forum.pjrc.com/threads/57515...Serial-Monitor

  14. #339
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    yes msadie you're right, FIFO wasn't meant to be used in enableMBInterrupt(). I will have to set a limiter based on MAXMB size so people would be forced to use enableFIFOInterrupt() instead

  15. #340
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    Quote Originally Posted by msadie View Post
    Serial.begin() belongs in setup().

    Per your code, it will only display more if you type "a" in the line at the top of the serial monitor and hit Send.
    Well that's what I get for copying and pasting code without fully understanding it. At least the serial monitor part of it is figured out, thanks for the help so far guys!

  16. #341
    Junior Member
    Join Date
    Aug 2020
    Posts
    7
    Hello,

    I am new in the CAN BUS world. Can you propose any document, what explains how FlexCAN work. I have read a lot of threads, but it is difficult to put all puzzles together. I could find details about the CAN BUS system itself, but I am searching a summary about the FlexCAN features, functions.

    Thanks

  17. #342
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    Check the link in the first post, it has a large readme, plus there are a couple examples in there. Some brief comments about functions can be found in the source file, but if you are looking for registers and clocks, you need to check the IMXRT1062 release manual

  18. #343
    Junior Member
    Join Date
    Aug 2020
    Posts
    7
    Hello tonton81,

    Thanks for your suggestion. I am reading them through.
    No, I am not a programmer, so I dont need the very deep water(registers, clocks), just would like to understand basic things like the mailbox concept, FIFO, callback, mailbox with interrupts, and so on. It is also not clear, where finishes the CANBUS, and where start FlexCan in the features. So really basic thinks :-)
    I have just found a short explanation about the mailbox concept, so it is a little bit more clear now.

  19. #344
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    it is a bit confusing at first, think of each mailbox as a random queue to hold incomming frames, can also be referred to as a message box. if you have 64 mailboxes, without reading any of them, you can hold up to 64 message frames before you start loosing additional frames. the idea is to read them as fast as possible sp remaining vacant mailboxes can store new frames. the basic concept is usually sending and receiving, when you want to go more advanced and filter out frames, automatic filtering is there to help you

  20. #345
    Junior Member
    Join Date
    Aug 2020
    Posts
    7
    Ok, I see. How can I read always the last message with the same ID and remove the older not read messages?
    I plan to use canbus for RC servo control. The main Teensy sends data in every 0.01s to the other Teensy, which generaters the RC PWM signal for the servos. So the most important think is to use the latest data. It is less problem, if 1-2 messages are lost.
    Another theme: there is a place where the canbus wires is bended continuously, so it will brake after a certain time. I want to double there the canbus wires with a simple Y connection, and connect both to Teensy Can1, Can2. I plan to use data from one of them, but I want to monitor both Can ports, the messages arrive continuously. If not, I change the data source to the good Can port (if needed), and send warning message to the main Teensy. What would be the best way to program this process?

  21. #346
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    you can lower the mailbox count if needed, example, instead of 64 mailboxes, you can setup 8, so you can store up to 8 latest frames. or, with FIFO, you'll have 6 latest frames with 8 transmit capable mailboxes by default. you will always get latest frames, the frames you dont use you will just not use em so theyre tossed. essentially you will always have latest data

  22. #347
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    I have some more dumb questions for you, I read the readme at the beginning. Actually pretty helpful so sorry I was negligent in reading that. I think I was a bit overwhelmed by what was going on.

    I am able to successfully transmit messages from the Teensy to the ecu that I am using. (YAY)

    Now I am trying to receive messages from the ecu back to the Teensy. My original thought was to just do a Can2.read(msg), but how do I go about manipulating the message (since the can packet is only able to hold 8 bytes of data and I have 2 bytes of data I want to manipulate). Is this where mailboxes come into play? Since the posts above me have been discussing that.

    I hope I actually asked a question that makes sense, I will share my code but just know I'm still learning coding and it might not totally make sense.

    Code:
    #include <FlexCAN_T4.h>
    
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> Can2;
    CAN_message_t msg,
    
    uint16_t Analog_In_38;
    bool Digital_In_28;
    bool Digital_In_29;
    float Engine_RPM;
    int8_t CoolantTempIn;
    int8_t CoolantTempOut;
    bool CoolFanStatus;
    bool CoolPumpStatus;
    byte EngineRPM_MSB;
    byte EngineRPM_LSB;
    
    void setup(void) 
    {
      pinMode(28,INPUT_PULLUP);
      pinMode(29,INPUT_PULLUP);
      pinMode(30,INPUT_PULLUP);
    
      Can2.begin();
      Can2.setBaudRate(1000000);
      
    }
    
    void loop() 
    {
      Digital_In_28 = digitalRead(28);
      Digital_In_29 = digitalRead(29);
      Analog_In_38 = analogRead(38);
    
      byte Analog38_LSB = Analog_In_38 & 0x00FF;
      byte Analog38_MSB = Analog_In_38 >>8;
    
      msg.id = 0x500;
      msg.len = 8;
      msg.buf[0] = Analog38_MSB;
      msg.buf[1] = Analog38_LSB;
      msg.buf[2] = Digital_In_28;
      msg.buf[3] = Digital_In_29;
      msg.buf[4] = 128;
      msg.buf[5] = 64;
      msg.buf[6] = 32;
      msg.buf[7] = 16;
    
      Can2.write(msg);
      Can2.read(msg);
    
    
      msg.id = 0x1001;
      msg.len = 8;
      msg.buf[0] = EngineRPM_MSB;
      msg.buf[1] = EngineRPM_LSB;
      msg.buf[2] = CoolantTempIn;
      msg.buf[3] = CoolantTempOut;
      msg.buf[4] = CoolFanStatus;
      msg.buf[5] = CoolPumpStatus;
      msg.buf[6] = 0;
      msg.buf[7] = 0;
    
      byte lowByte=msg.buf[1];
      byte highByte=msg.buf[0];
      Engine_RPM = ((int) highByte << 8 )| lowByte; 
    
      Serial.print("Analog38LSB:");
      Serial.println(Analog38_LSB);
      Serial.print("Analog38MSB:");
      Serial.println(Analog38_MSB);
    
      Serial.print("Digital 28 is:");
      Serial.println(Digital_In_28);
      Serial.print("Digital 29 is:");
      Serial.println(Digital_In_29);
      Serial.print("Analog 38 is:");
      Serial.println(Analog_In_38);
      Serial.print("Engine_RPM:");
      Serial.println(Engine_RPM);
      delay(250);
    
    }
    Last edited by FollowTheVoodoo; 08-05-2020 at 05:40 AM. Reason: Adding additional thoughts.

  23. #348
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,463
    think of a mailbox as just a queue. now all your data is in queues.

    When you do a Can2.read(msg), that is actually polling the mailboxes, and not interrupt driven. You can start with that for now and if you deem your CAN traffic is critical, you can move to interrupt mode.

    now when you do a read(), your "msg" frame is updated (if a frame os available. you however didnt check the data and instead overwrote it, check
    Code:
    Can2.write(msg);
      Can2.read(msg);
    msg should have new frame data, but then you overwrite it.
    read the variables and see what data you get

  24. #349
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    Quote Originally Posted by tonton81 View Post
    think of a mailbox as just a queue. now all your data is in queues.

    When you do a Can2.read(msg), that is actually polling the mailboxes, and not interrupt driven. You can start with that for now and if you deem your CAN traffic is critical, you can move to interrupt mode.

    now when you do a read(), your "msg" frame is updated (if a frame os available. you however didnt check the data and instead overwrote it, check
    Code:
    Can2.write(msg);
      Can2.read(msg);
    msg should have new frame data, but then you overwrite it.
    read the variables and see what data you get
    Was able to get it work, thanks for all the help (and the patience!) you too msadie

  25. #350
    Junior Member
    Join Date
    Apr 2020
    Posts
    17
    Hey guys, I've run into a problem using Teensy 4.1 Flexcan_t4 and I2C. So for reference, i have a Teensy 4.1 driving a pair of nextion screens displaying data from an ecu as a dashboard. I have 2 separate Can lines, one from the ecu and another for inputs from external sensor modules. Everything is working absolutely fine on the canbus side of things but here is where the problem comes to light. I have a 10 degrees of freedom (GY-87) module i am trying to connect for altitude and g force data via I2C. Before connecting it to the Dash setup, had written and tested and calibrated the I2C commands and back end math with a Teensy 4.0 so i know the code is correct on that front. Once connected to the Teensy 4.1 i started getting some readings from the sensor that are way out of whack. After trying a bunch of stuff, i found that by commenting out the call lines that calls on the routine that reads from the two Canbus lines, the data from the GY-87 is correct.

    I have tried combinations of moving between the Can1, Can2 and Can3 inputs but no matter what i do, if Can is read on any one of the channels, the I2C data goes out of whack. Has anyone come across a conflict between can and I2C that might shed some light on the situation? Also, is there a way to end the can library in the sub routine as so i can start the library and stop the library in the subroutine as a crude work around? something like a Can0.end()??

Posting Permissions

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