Forum Rule: Always post complete source code & details to reproduce any issue!
Page 42 of 43 FirstFirst ... 32 40 41 42 43 LastLast
Results 1,026 to 1,050 of 1071

Thread: FlexCAN_T4 - FlexCAN for Teensy 4

  1. #1026
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    do a mailboxStatus(), if it still stays there after you stop transmitting, verify your baudrate, terminations, transceiver connections. it will stay in the mailbox and software has no control over that, it sits there because you have a connection issue, even with a node that doesn't ACK it, that's an expected behaviour.

  2. #1027
    Junior Member
    Join Date
    Jun 2022
    Posts
    2
    Hi thanks for the reply.

    Inside my loop(), there is a function called can2.mb() that calls the mailboxStatus(). The message is transmitting as I have hooked up a Mircrochip CAN Bus Analyser to the bus and verified that it is transmitting.

    But the message is only transmitting when I call the function can2.setMB(MB8, TX, STD), which I am trying to figure out why. Messages stay in the mailbox but are not transmitted when the setMB() is not called.

  3. #1028
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    Is there any data on the bus? If it's in a TX mailbox it should be writing out, what does mailboxstatus print out?

  4. #1029
    Junior Member
    Join Date
    Jun 2022
    Posts
    1
    I am looking for a short explanation of how to properly use the mailboxes, write function and sequential flag to send regular timed can messages.

    Maybe you could point me to a previous post or take a look at my use case below!

    I am implementing a very limited CAN open library... very limited. Only passing a few messages to a motor controller to program it to self report it's position.
    Below is a class responsible for holding a collection of CAN_message_t objects and a couple methods for operating on them. My goal is to be able to create my Instruction class with the particular messages in it that I want to send them in order with a short delay between each one.

    After some testing I have determined I am not using the library correctly. As when I us the .write() method I end up continually writing to the can bus.

    Qs:
    * Is there a way to send just one message at a time?
    * How do I create delays in-between messages?
    => I have seen the example code with the timeout code however this is not quite the functionality I am looking for.
    * How do you send messages in a particular order?
    => I have identified the sequential transmission flag, however I am not sure exactly how this works

    As I have spent more time learning about this library I have really seen how it is crafted well, so I want to express my appreciation in advance for any help you can provide

    full source code:

    Code:
    #ifndef _CANOPEN_
    #define _CANOPEN_
    
    #include <Arduino.h>
    #include <FlexCAN_T4.h>
    
    /*
     * Contains several individual
     * CANopen messages that can
     * be sent sequentially
     */
    template <size_t N>
    class Instruction
    {
    public:
        template <CAN_DEV_TABLE _bus,
                  FLEXCAN_RXQUEUE_TABLE _rxSize,
                  FLEXCAN_TXQUEUE_TABLE _txSize>
        void sendInstruction(FlexCAN_T4<_bus, _rxSize, _txSize> canBus);
        void printInstruction();
        void addFrame(uint32_t header, uint8_t buf[8]);
    
    private:
        CAN_message_t msgs[N]; // array of messages to send
        int index = 0;
        template <CAN_DEV_TABLE _bus,
                  FLEXCAN_RXQUEUE_TABLE _rxSize,
                  FLEXCAN_TXQUEUE_TABLE _txSize>
        void transmitFrame(FlexCAN_T4<_bus, _rxSize, _txSize> canBus, CAN_message_t &msg);
        void errorHandler(int e);
    };
    
    template <size_t N>
    template <CAN_DEV_TABLE _bus,
              FLEXCAN_RXQUEUE_TABLE _rxSize,
              FLEXCAN_TXQUEUE_TABLE _txSize>
    void Instruction<N>::sendInstruction(FlexCAN_T4<_bus, _rxSize, _txSize> canBus)
    {
        for (unsigned int i = 0; i < N; i++)
        {
            transmitFrame(canBus, this->msgs[i]);
            // TODO delay or find a way to only send one message or delay
            // TODO send in sequential order
        }
        return;
    }
    
    template <size_t N>
    template <CAN_DEV_TABLE _bus,
              FLEXCAN_RXQUEUE_TABLE _rxSize,
              FLEXCAN_TXQUEUE_TABLE _txSize>
    void Instruction<N>::transmitFrame(FlexCAN_T4<_bus, _rxSize, _txSize> canBus, 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();
        canBus.write(msg);
        return;
    }
    
    template <size_t N>
    void Instruction<N>::addFrame(uint32_t header, uint8_t buf[8])
    {
    
        CAN_message_t msg;
    
        msg.id = header;
    
        for (int i = 0; i < 8; i++)
        {
            msg.buf[i] = buf[i]; // copy buf into new message
        }
    
        this->msgs[this->index] = msg; // assign member var and increment index
        this->index++;
        return;
    };
    
    template <size_t N>
    void Instruction<N>::printInstruction()
    {
        Serial.println("=======================");
        Serial.print("index: ");
        Serial.println(this->index);
        for (int i = 0; i < this->index; i++)
        {
            Serial.print(i);
            Serial.print(" : ");
            Serial.println(this->msgs[i].id, HEX);
            for (int j = 0; j < 8; j++)
            {
                Serial.print(" =>");
                Serial.println(this->msgs[i].buf[j], HEX);
            }
        }
    
        return;
    }
    
    template <size_t N>
    void Instruction<N>::errorHandler(int e)
    {
        switch (e)
        {
        case 102: // too may frames added
            Serial.println("**ERROR**");
            Serial.println("Attempted to add too many frames,");
            Serial.print("   => Current frame limit: ");
            Serial.println(N);
            Serial.println("Increase your instruction size...");
            break;
        default:
            Serial.println("Something went wrong");
            break;
        }
        return;
    }
    
    #endif
    
    #ifndef _CANOPEN_MSGS_
    #define _CANOPEN_MSGS_
    /* this would most likely be moved to a file */
    
    /* set Number of mapped objects TPDO 1 to 0x00 */
    uint8_t msg0[] = {
        0x2f,
        0x00,
        0x1A,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00};
    
    /* set TPDO 1 mapping information 1 to 0x60640020 */
    uint8_t msg1[] = {
        0x23,
        0x00,
        0x1a,
        0x01,
        0x20,
        0x00,
        0x64,
        0x60};
    
    /* set Number of mapped objects TPDO 1 to 0x01 */
    
    uint8_t msg2[] = {
        0x2f,
        0x00,
        0x1a,
        0x00,
        0x01,
        0x00,
        0x00,
        0x00};
    
    /* set Transmission type TPDO 1 to 0x01 */
    uint8_t msg3[] = {
        0x2f,
        0x00,
        0x18,
        0x02,
        0x01,
        0x00,
        0x00,
        0x00};
    
    /* set Communication Cycle Period to 0x000186a0 */
    uint8_t msg4[] = {
        0x23,
        0x06,
        0x10,
        0x00,
        0xa0,
        0x86,
        0x01,
        0x00};
    
    /* set COB-ID  SYNC message to 0xc0000080 */
    uint8_t msg5[] = {
        0x23,
        0x05,
        0x10,
        0x00,
        0x80,
        0x00,
        0x00,
        0xc0};
    
    /* start remote node - node 1 */
    uint8_t msg6[] = {
        0x01,
        0x01,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00};
    
    #endif

  5. #1030
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    Hardware only sends transmission once but only if it is successful. It will retry until a valid ACK occurs and then it can continue to next frame. Be sure a node is on the bus to ACK it and check the wiring to make sure all is good. I don't see any loop code above so cant see if your sending endlessly or it being an ACK issue. If msg.seq = True, messages will be queued and sent in order, this uses the absolute first mailbox to do so. without seq bit set, it will sent to any tx mailboxes, and that order of transmission between multiple transmits cannot be controlled

  6. #1031
    Junior Member
    Join Date
    Jun 2022
    Posts
    4
    Hello guys,
    I've been using latest flexcan for a while but only now I've identified a strange behaviour that is driving me crazy.
    The hardware is pretty standard and used it before without teensy, so I assume no problem there.
    The problem is, after a while CAN communication stop working, even if I reflash or restart teensy, does not work.
    Only when I power cycle the teensy the CAN starts working again.
    I've tried to CAN.begin() or CAN.reset() or even create a new instance when the comunnication is lost without sucess.
    Doest anybody have this problem and can help me to solve it?

  7. #1032
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    203
    Which CAN transceiver are you using ? How is it connected to the Teensy ?

    Post a photo of your setup.

  8. #1033
    Junior Member
    Join Date
    Jun 2022
    Posts
    4
    Quote Originally Posted by skpang View Post
    Which CAN transceiver are you using ? How is it connected to the Teensy ?

    Post a photo of your setup.
    Hello skpang,

    I'm using standard mcp2551 as you can see in my schematic below, I've done a pcb to connect everything.
    I've been using this same schematic for years without problems but I was used to ST and other libraries.
    Still, dont know if this is a hardware thing or library issue.

    https://ibb.co/K6mbMXB

  9. #1034
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    203
    Which version of Teensy are you using ?

  10. #1035
    Junior Member
    Join Date
    Jun 2022
    Posts
    4
    Quote Originally Posted by skpang View Post
    Which version of Teensy are you using ?
    I'm using teensy 3.6 and I update today to the latest version flexcan_t4 on github. Still same problem as previous versions.

  11. #1036
    Senior Member
    Join Date
    Jan 2015
    Location
    UK
    Posts
    203
    The MCP2551 is 5v supply with 5v IO. The Teensy 3.6 is not 5v tolerant on the input. You may have damaged the input pin.

    I would use the MCP2562 with 5v supply and 3.3v IO.

  12. #1037
    Junior Member
    Join Date
    Jun 2022
    Posts
    4
    Quote Originally Posted by skpang View Post
    The MCP2551 is 5v supply with 5v IO. The Teensy 3.6 is not 5v tolerant on the input. You may have damaged the input pin.

    I would use the MCP2562 with 5v supply and 3.3v IO.
    OK, that could be a problem, but the input is not damaged because after a power cycle on teensy everything seems to work fine.
    Can the input be clamped by internal diodes or protected and only a power cycle solves this?

  13. #1038
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    181
    Hello,

    I use flexcan_t4 library for the first time and I figure that when I start the CAN, there are messages on Serial0 with a teensy 4.0.

    My code :
    Code:
      Can0.begin();
      Can0.setBaudRate(CANSpeed);
      Can0.setMaxMB(16);
      Can0.enableFIFO();
      Can0.enableFIFOInterrupt();
      Can0.onReceive(canSniff);
      Can0.mailboxStatus();
      return;
    What is outputted to serial :
    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
    How can I disable library messages ? I use Serial for communication with another devices and can't have any "unknown" messages.

    Thank you,
    Manu

  14. #1039
    Senior Member
    Join Date
    Jan 2015
    Location
    France
    Posts
    181
    Sorry, I found :

    Code:
    Can0.mailboxStatus();

  15. #1040
    Junior Member
    Join Date
    Jun 2022
    Location
    Lyon, France
    Posts
    5
    Hi everybody,
    I hardly try to make my CAN works on a bus of 5 units. The first and the last have terminaison resistor of 12O ohm. Tranceivers : MCP2551 5 volt
    I tried to use CAN2 on teensy 4.1 but there is no signal on CTX2.
    Here my code :
    Code:
    #include <FlexCAN_T4.h>
    #include <Arduino.h>
    #include <Bounce.h>
    #include <RGB_LED.h>
    #include "music.h"
    #include "config.h"
    
    void canCallback(const CAN_message_t &msg);
    
    void canSend(uint8_t data);
    
    void parseCAN(CAN_message_t msg);
    
    FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can;
    CAN_message_t in_msg;
    Bounce ir_detect(DETEC_PIN, 100);
    RGB_LED rgb_led(RED_PIN, GREEN_PIN, BLUE_PIN);
    #ifdef ARCHE_MASTER
    Metro timer = Metro(INTERVAL_PONG);
    Metro pong = Metro(INC_LED_PONG);
    bool pong_state = true;
    uint8_t led_inc = 0;
    #endif
    
    void setup() {
        pinMode(DETEC_PIN, INPUT);
    #if DBG
        Serial.begin(115200);
        while (!Serial) { delay(10); }
    #endif
        DBG_PRINT("Arche : ");
        DBG_PRINTLN(ARCHE_NO);
        can.begin();
        can.setBaudRate(500000);
        can.setMaxMB(16);
        can.enableFIFO();
        can.enableFIFOInterrupt();
        can.onReceive(canCallback);
        can.mailboxStatus();
    
        //music_init();
        rgb_led.set(0, 0, 0);
    #ifdef ARCHE_MASTER
        timer.reset();
    #endif
    }
    
    void loop() {
        can.events();
        rgb_led.run();
        if (can.read(in_msg)) {
            DBG_PRINTLN("CAN RX");
            parseCAN(in_msg);
        }
        delay(20);
    }
    
    void canCallback(const CAN_message_t &msg) {
        parseCAN(msg);
    }
    
    void canSend(uint8_t data) {
        CAN_message_t send_msg;
        send_msg.id = ARCHE_NO;
        send_msg.id = 0x00;
        send_msg.len = CAN_FRAME_LEN;
        send_msg.buf[0] = START_CAN_FRAME;
        send_msg.buf[1] = data;
        send_msg.buf[2] = STOP_CAN_FRAME;
        can.write(send_msg);
        //can.setMB(MB8, TX, STD);
    }
    
    void parseCAN(CAN_message_t msg) {
        DBG_PRINTF("CAN RX ID : %d | Len : %d\n", msg.id, msg.len);
        DBG_PRINT("Data : ");
    #if DBG
        for (int i = 0; i < msg.len; i++) {
            DBG_PRINT(msg.buf[i]);
        }
    #endif
        DBG_PRINTLN();
    
    #ifdef ARCHE_MASTER
        if ((msg.id > 0x01) && (msg.id < 0x06) && (msg.len == CAN_FRAME_LEN)) {
            if (msg.buf[0] == START_CAN_FRAME && msg.buf[2] == STOP_CAN_FRAME) {
                if (msg.buf[1] == DETECT_CAN_FRAME) {
                    DBG_PRINTLN("DETECT");
                    timer.reset();
                    pong_state = false;
                } else {
                    DBG_PRINTLN("Wrong CAN frame");
                }
            }
        }
    #else
        if ((msg.id > 0x00) && (msg.id < 0x06) && (msg.len == CAN_FRAME_LEN)) {
            if (msg.buf[0] == START_CAN_FRAME && msg.buf[2] == STOP_CAN_FRAME) {
                if (msg.buf[1] == DETECT_CAN_FRAME) {
                    rgb_led.set(0, 0, 0);
                } else if ((msg.buf[1] & 0xD0) == PONG_CAN_FRAME) {
    #if ARCHE_NO == 2
                    if (msg.buf[1] == 0xD1) {
                        rgb_led.set(LED_COLOR);
                    } else if (msg.buf[1] == 0xD2) {
                        rgb_led.set(0, 0, 0);
                    }
    #elif ARCHE_NO == 3
                    if (msg.buf[1] == 0xD2) {
                    rgb_led.set(LED_COLOR);
                    }
                else if (msg.buf[1] == 0xD3) {
                    rgb_led.set(0,0,0);
                }
    #elif ARCHE_NO == 4
                if (msg.buf[1] == 0xD3) {
                    rgb_led.set(LED_COLOR);
                    }
                else if (msg.buf[1] == 0xD4) {
                    rgb_led.set(0,0,0);
                }
    #elif ARCHE_NO == 5
                if (msg.buf[1] == 0xD4) {
                    rgb_led.set(LED_COLOR);
                    }
                else if (msg.buf[1] == 0xD0) {
                    rgb_led.set(0,0,0);
                }
    #endif
    
                } else {
                    DBG_PRINTLN("Wrong CAN frame");
                }
            }
        }
    #endif
    }
    And the serial monitor :
    Code:
    FIFO Enabled
    Mailboxes:
    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
    Mailboxes are empty after sending something.
    If anyone can help me I would be amazing.
    Thanks in advance
    Axoul

  16. #1041
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    are you using pins 0 & 1 for CAN2?
    are you using level shifters? teensy is 3.3v
    is the Rs pin driven low?

  17. #1042
    Junior Member
    Join Date
    Jul 2022
    Posts
    2
    Howdy, In the process of porting my code tested on a UNO coded for polling to a teensy 4.0 using FIFO with interrupts. Everything connects, writes, and reads fine however the frames are not ordered as seen in the logs below. I'm expecting Oil and Coolant temp to be cycled in order. I’m using UDS over canbus whereby data requests is similar to OBD ie: request/receive. Filtering is working as expected. The polling speed on either the UNO or Teensy is constant 30ms which is governed by the OBD gateway in the car.

    I have read a few posts suggesting to use message sequencing (msg.seq=1), setMaxMB(9) to setup only 1 transmit MB or removing .events in the loop but have had no joy finding the correct combination. Obviously I can just move back to polling but most of the threads that I have read suggest to use interrupts with the teensy due to the processing speed.

    Below is a snippet of the pertinent code elements and the associated serial monitor outputs. Any guidance or recommendations appreciated.

    Code:

    Code:
    #include <FlexCAN_T4.h>
    #include <EasyNextionLibrary.h>
    FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can1;
    
    #define OUTPUT_TERMINAL true                                                            			// set to false not to output to serial terminal and before production compile
    #define OUTPUT_TERMINAL_SERIAL if(OUTPUT_TERMINAL)Serial
    
    CAN_message_t msg;
    
    void canSniff(const CAN_message_t &msg) {
      #if OUTPUT_TERMINAL == true 
        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++ )                                                         // print the data
        { 
            Serial.print(" ");
            if (msg.buf[i] < 16)                                                                    	   // Pad with 0 for HEX values less than 0x10
            {
                Serial.print("0");
            } 
            Serial.print(msg.buf[i], HEX);
        }
        if (msg.len == 6)                                                                           	   // Padding out with 00 for null byte fields so that debug output table looks nice
        { 
            Serial.print(" ");
            Serial.print("00");
        }
        Serial.print(" ");
      #endif
      unsigned int sensorID = (msg.buf[3] << 8) | msg.buf[4];               							          
      switch(sensorID){
        case 0x5822:                                                         				  // HEX 5822 - Oil Temperature in C
            {
            unsigned char OilTemperature = msg.buf[5];
            OilTemperature = OilTemperature - 60;
            #if OUTPUT_TERMINAL == true 
                Serial.print("OilTemperature:\t\t");
                Serial.print(OilTemperature);
            #endif    
            }                    
        break; 
        case 0x4300:                                                         				 // HEX 4300 - Coolant Temperature in C
            {
            unsigned char CoolantTemperature = msg.buf[5];
            CoolantTemperature = CoolantTemperature * 0.75 - 48;
            #if OUTPUT_TERMINAL == true 
                Serial.print("CoolantTemperature:\t");
                Serial.print(CoolantTemperature);
            #endif 
            }                    
        break;
      }
      Serial.print("\tTS: "); Serial.print(millis());
      Serial.print("\tTS: "); Serial.println(msg.timestamp);
    }
    
    void setup(void) {
      #if OUTPUT_TERMINAL == true
        Serial.begin(250000); delay(6000);                                              		  // Delay to allow PlatformIO console monitor time to start. Otherwise miss the initial maiboxstatus
      #endif
    
      can1.begin();
      can1.setBaudRate(500000);
      can1.setMaxMB(16);
      //can1.setMaxMB(9);
      //can1.setMaxMB(32);
      can1.enableFIFO();
      can1.enableFIFOInterrupt();
      
      can1.setFIFOFilter(REJECT_ALL);
      can1.setFIFOFilter(0, 0x612, STD); 
      can1.onReceive(canSniff);
      #if OUTPUT_TERMINAL == true
        can1.mailboxStatus();
      #endif
    }
    
    void rOilTemperature(){
        //unsigned char stmp[8] = {0x12,0x03,0x22,0x58,0x22,0x00,0x00,0x00}; 
        msg.buf[0] = 0x12; msg.buf[1] = 0x03; msg.buf[2] = 0x22; msg.buf[3] = 0x58; msg.buf[4] = 0x22; msg.buf[5] = 0x00; msg.buf[6] = 0x00; msg.buf[7] = 0x00;
        can1.write(msg);                                                
    }
    
    void rCoolantTemperature(){
        //unsigned char stmp[8] = {0x12,0x03,0x22,0x43,0x00,0x00,0x00,0x00};
        msg.buf[0] = 0x12; msg.buf[1] = 0x03; msg.buf[2] = 0x22; msg.buf[3] = 0x43; msg.buf[4] = 0x00; msg.buf[5] = 0x00; msg.buf[6] = 0x00; msg.buf[7] = 0x00;
        can1.write(msg);                                              
    }
    
    void loop() {
      can1.events();
      //msg.seq = 1; 
      msg.id = 0x6F1; msg.len = 8;
      rCoolantTemperature();
      rOilTemperature(); 
    }
    setMaxMB(16)

    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: 6 EXT: 0 TS: 45635 ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16267
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 60608 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:          28      TS: 16297
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 9926  ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16327
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 24994 ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16357
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 39848 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:          28      TS: 16387
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 54940 ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16417
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 4710  ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16448
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 19326 ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16477
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 34656 ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16508
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 49272 ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16537
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 64578 ID: 612 Buffer:  F1 04 62 43 00 65 00 CoolantTemperature:      27      TS: 16568
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 13777 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:          28      TS: 16597
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 TS: 28988 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:          28      TS: 16628

    setMaxMB(9)

    Code:
    FIFO Enabled --> Interrupt Enabled
            FIFO Filters in use: 8
            Remaining Mailboxes: 1
                    MB8 code: TX_INACTIVE
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:            28      TS: 8309
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 43 00 66 00 CoolantTemperature:        28      TS: 8332
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 43 00 66 00 CoolantTemperature:        28      TS: 8361
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 43 00 66 00 CoolantTemperature:        28      TS: 8391
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:            28      TS: 8421
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:            28      TS: 8452
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 43 00 66 00 CoolantTemperature:        28      TS: 8482
    MB 99 OVERRUN: 0 LEN: 6 EXT: 0 ID: 612 Buffer:  F1 04 62 58 22 58 00 OilTemperature:            28      TS: 8511
    Last edited by MR RIZK; 07-03-2022 at 02:20 PM.

  18. #1043
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    you shouldn't need to strip mailboxes down to one using msg.seq = 1, it will only output to the absolute first mailbox. also you don't need events() in loop if you want direct firing interrupts, but that's optional. As far as I see your loop is flooding the bus and the ECU is responding whatever is available in memory of the burst. At this point since you're transmitting too fast to the ECU, the ECU will block some requests until it finishes with the response, which will flow back to you in a seemingly unordered state, but in reality it's the order the ECU prepared the response during a request while invalidating the excessive frames.usually you need at least a 10ms gap between ECU requests, I don't see any delays in your loop(), add a delay(15) somewhere in your loop and try it again

    once it works, replace delay with millis() or elapsedmillis.

    yes the 30ms is consistant with the gateway's responses, but your transmission speeds are too fast for the ECU/gateway to handle when you are constantly sending them in a forever loop, if it responds at 30, send at 45ms intervals for example, in some cases ECU responses may come quicker if it's not being flooded or talked to in awhile
    Last edited by tonton81; 07-04-2022 at 03:13 AM.

  19. #1044
    Junior Member
    Join Date
    Jul 2022
    Posts
    2
    Quote Originally Posted by tonton81 View Post
    you shouldn't need to strip mailboxes down to one using msg.seq = 1, it will only output to the absolute first mailbox. also you don't need events() in loop if you want direct firing interrupts, but that's optional. As far as I see your loop is flooding the bus and the ECU is responding whatever is available in memory of the burst. At this point since you're transmitting too fast to the ECU, the ECU will block some requests until it finishes with the response, which will flow back to you in a seemingly unordered state, but in reality it's the order the ECU prepared the response during a request while invalidating the excessive frames.usually you need at least a 10ms gap between ECU requests, I don't see any delays in your loop(), add a delay(15) somewhere in your loop and try it again

    once it works, replace delay with millis() or elapsedmillis.

    yes the 30ms is consistant with the gateway's responses, but your transmission speeds are too fast for the ECU/gateway to handle when you are constantly sending them in a forever loop, if it responds at 30, send at 45ms intervals for example, in some cases ECU responses may come quicker if it's not being flooded or talked to in awhile
    Thanks for the tips. I checked my UNO code and the reason it works in the correct sequenced order is because I had a check in their waiting for the frame to hit the buffer before processing. As suggested for testing purposes I had to add a 30ms delay on each sensor request which fixed the sequencing. Anything lower no dice.

    I found this article which explained the reasons to use millis() vs delay LINK which all makes sense however I don't see an elegant way of incorporating this into my sketch. Its hard to explain but I will try.

    The output is to a nextion display that has multiple pages. Each page has a different set of sensors with some that overlap with other pages. When sending data to the display I'm only sending sensor data that is displayed on that page. There are about 50 sensors in total. When using the polling method I can execute each sensor function call sequentially within the loop and the parsing function will wait till the frame exists in the buffer before doing the calculations. In essence the "wait" is controlled by the parsing function. Using interrupts the "wait" needs to be controlled within the Loop function to control when the sensor function should request the data ie pre vs post. This is where I'm stuck in the logic on how to only request the data 30ms apart while keeping the requests ordered per page.

    Hope that makes sense. Any pseudo wisdom appreciated.

  20. #1045
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    what i always do (my own preference of course) is setup a scoped millis() near the action you want to do, so in the loop i would put:

    Code:
    void loop() {
      static uint32_t coolant_timer = millis();
      if ( millis() - coolant_timer >= 30 ) {
        rCoolantTemperature():
        coolant_timer = millis();
      }
    }
    this will run your function every 30ms

    If your ECU can process both frames at same time and send them back in same order (provided it's not flooded with requests), then you can put both functions in there, if not, you could tell the scope to run a next command after 30 ms


    Code:
    void loop() {
      static uint32_t coolant_timer = millis();
      static int send_switch = 0;
      if ( millis() - coolant_timer >= 30 ) {
        if ( send_switch > 1 ) send_switch = 0;
        if ( send_switch == 0 ) rCoolantTemperature():
        if ( send_switch == 1 ) rOilTemperature();
        send_switch++;
        coolant_timer = millis();
      }
    }

  21. #1046
    Junior Member
    Join Date
    May 2018
    Posts
    19
    This works great! I'm streaming data on several vehicles now, and I want to start sending OBD2 PID requests. I saw the example for writes. Should I use this as a basis? What configurations do I need to worry about?

    Example from git below. I assume those write options are either/or?

    void loop() {
    static uint32_t sendTimer = millis();
    if ( millis() - sendTimer > 1000 ) {
    uint8_t buf[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
    const char b[] = "01413AAAAABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCD EFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQR STUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ012345 6789";
    ISOTP_data config;
    config.id = 0x666;
    config.flags.extended = 0; /* standard frame */
    config.separation_time = 10; /* time between back-to-back frames in millisec */
    tp.write(config, buf, sizeof(buf));
    tp.write(config, b, sizeof(b));
    sendTimer = millis();
    }
    }

  22. #1047
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    well thats for isotp.

    for pid requests you can just use the following (edited as needed)

    Code:
        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);

  23. #1048
    Junior Member
    Join Date
    May 2018
    Posts
    19
    Damn that was fast. Can I drop that into the isotp sketch I stumbled on, or is that a different world?

  24. #1049
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    4,074
    the isotp is an addon, you can use both as needed in same sketch

  25. #1050
    Junior Member
    Join Date
    May 2018
    Posts
    19
    Thank you. What an amazing service you are providing. Teensy is an amazing "grown up" Arduino option, and your library is an amazing add to that for car dudes. I couldn't imagine a better development platform.

Posting Permissions

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