FlexCAN_T4 - FlexCAN for Teensy 4

Ive been using the TI transceiver that mjs linked to with a T4 on a 2016 Golf GTI with no issues.
Been working solid for the past 6 months on both the T3.2/T4
 
I very quickly tried wiring up a spare transceiver this morning (same one as before), and this time there were no messages coming through. I'd cut out the 120 ohm resistor, and wired it to pins 0 and 1 instead. I'll double check wiring and everything when I get home today, but it's starting to seem like those transceivers might be the issue. I should have the waveshare unit waiting for me when I get home too, so I'll give that one a try tonight.
Thanks for all the help and feedback, everyone.
 
Even though this may have been mentioned, can you conform TX on the Teensy is going to TX on the transceiver and the same for RX on both side?
I initially was getting nothing, until I discovered it should be wired as above.
 
That was the way I had it wired up, yes. I may have messed it up this morning in my rush trying the second transceiver, but I found a little more info about people having trouble with this particular board.
Hopefully the waveshare board fixes the issue tonight.
 
Tried out the Waveshare board: it works! Does exactly what I'd hoped.
Will try the previous transceiver board one more time just for fun (I think I may have plugged in CanH/L to a couple of analog inputs instead of the Can ports in my haste this morning).
 
Tried out the Waveshare board: it works! Does exactly what I'd hoped.
Will try the previous transceiver board one more time just for fun (I think I may have plugged in CanH/L to a couple of analog inputs instead of the Can ports in my haste this morning).

Did you have a play around with the other transceiver board?

I get very odd behaviour when not using a Waveshare board too. Similar projects fwiw, mine is a dash display for a DTA ECU.

My experience is repeated data packets, rather than all of them. I get this with waveshare knock-offs as well as the smaller Sn65 boards, but as soon as I use a Waveshare board, boom it works.
 
Haven't had a chance yet... the project my Teensy is contributing to needed a LOT of other stuff (I had to fabricate a full exhaust system, among many other things) - but as of yesterday, the car is driving, so I should have a little time to test out the other transceiver this week. With the Waveshare board, the Teensy is doing an awesome job, I'll share some details when I get a chance to write things up.
 
I've been building a CAN gateway using this library and I have been having a bit of trouble. My goal is to forward messages from CAN2 to CAN1 as fast as possible while maintaining sequence. When I try to set myMsg.seq = 1, the bus intermittently stops all outgoing traffic until reset. After some investigation, I found a message somehow gets stuck in the transmit mailbox with the status "transmitting" while the txBuffer fills up.

My first unsuccessful attempt:
Code:
#include <FlexCAN_T4.h>

// CAN bus defines
#define VCAN_SILENT_PIN 2
#define VCAN_TERMINATOR_PIN 8
#define LCAN_SILENT_PIN 20

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> LCAN;
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> VCAN;

void setup() {
  pinMode(LCAN_SILENT_PIN, OUTPUT);
  pinMode(VCAN_SILENT_PIN, OUTPUT);
  pinMode(VCAN_TERMINATOR_PIN, OUTPUT);

  digitalWrite(LCAN_SILENT_PIN, LOW);   /* optional transceiver silent pin: HIGH = Silent */
  digitalWrite(VCAN_SILENT_PIN, LOW);  /* optional transceiver silent pin: HIGH = Silent */
  digitalWrite(VCAN_TERMINATOR_PIN, HIGH); /* optional bus terminator enable pin*/

  Serial.begin(500000);

  // Setup VCAN
  VCAN.begin();
  VCAN.setBaudRate(500000);
  VCAN.enableFIFO();
  VCAN.enableFIFOInterrupt();
  VCAN.onReceive(canWrite);

  // Setup LCAN
  LCAN.begin();
  LCAN.setBaudRate(500000);
  LCAN.mailboxStatus();

  delay(100);
}

void loop() {
  VCAN.events();
  LCAN.events();
}

void canWrite(const CAN_message_t &msg) {
  CAN_message_t myMsg;
  myMsg = msg;
  myMsg.seq = 1;
  LCAN.write(myMsg);
}

The best result I have gotten so far has been removing VCAN.onReceive(canWrite) and using ext_output1 as follows:
Code:
void ext_output1(const CAN_message_t &msg) {
  CAN_message_t myMsg;
  myMsg = msg;
  myMsg.seq = 1;
  LCAN.write(myMsg);
}

This method seems more robust (up to several minutes before stopping), but often drops a certain short 1byte message. The trouble seems related to burst traffic. I can send generated frames at 75% bus load (3 frames with 8 bytes each at 1ms intervals) without trouble. But when I playback recorded vehicle data with ~35% bus load the issue starts.

Does anyone see issues with my code or have any ideas on causes? Thanks in advance!

EDIT: I'm using TI TCAN330GD transceivers, FWIW.
 
Have you tried setting setClock to 60MHz? Thats what I am using in my vehicle at 500kbps

The background handler works because it is direct, no filter, to all receptions, without using the queue. Perhaps the bus is filling the queue too fast? You can check the RX queue size during runtime by printing next 12 bits of events(). 0xFFF000 masked >> 12 will return the value of frames in the queue. If you prefer not using the queue, the external callback will work, but there will be no software filter for canids in that function

For bridging it is good to have direct callback response system like your using via external callback, queues in bridge mode is kinda useless as it will follow the delays of the loop for each events() cycle. If your filtering specific frames or doing normal CAN, using it normally is fine

Sequential frames require events() to be triggered as well. So keep that spinning or try without sequential bit if ordering is not important, you could fill all the TX mailboxes that way
 
Last edited:
Have you tried setting setClock to 60MHz? Thats what I am using in my vehicle at 500kbps

The background handler works because it is direct, no filter, to all receptions, without using the queue. Perhaps the bus is filling the queue too fast? You can check the RX queue size during runtime by printing next 12 bits of events(). 0xFFF000 masked >> 12 will return the value of frames in the queue. If you prefer not using the queue, the external callback will work, but there will be no software filter for canids in that function

For bridging it is good to have direct callback response system like your using via external callback, queues in bridge mode is kinda useless as it will follow the delays of the loop for each events() cycle. If your filtering specific frames or doing normal CAN, using it normally is fine

Sequential frames require events() to be triggered as well. So keep that spinning or try without sequential bit if ordering is not important, you could fill all the TX mailboxes that way


Thanks for the feedback and suggestions.

Setting the clock to 60MHz doesn't seem to improve the result. The RX queue size always returns 0. Also, if I put a incremental counter in the callback, it always ends up equal to the correct number of messages.

The testing I've done so far indicates a TX side problem. Even after the bus locks up, the external callback is still being executed for each incoming message. If I print mailboxStatus when locked up, it will say "MB8 code: TX_DATA (Transmitting) .... (ID: 0x158)..." for example, and this frame will never clear the mailbox until reset. It seems like the frame is somehow stuck in the move-out process and is holding up the queue.

If I abort the transmission stuck in the mailbox, the CODE stays TX_ABORT even after asserting the IFLAG. If I understand the ref docs, this indicates one of the following conditions:
  • The module loses the bus arbitration
  • There is an error during the transmission
  • The module is put into Freeze Mode
  • The module enters in BusOff state
  • There is an overload frame
After reading the abort CODE and asserting the IFLAG, if I manually set CODE to TX_INACTIVE, all of the queued messages pile out.

Maybe my next step will be going through the above list and figuring out if any registers indicate those issues/modes/states.
 
Ive heard also some transceivers cause lockup issues on the bus. But in all honestly if there was an issue with transmitting then TeensyCAN wouldn't be working as I've tested it with 1024 and 2048 byte array transfers over CANbus with CRC validation. If there was a transmit issue and lockup, I'd check the transceiver. Some users have had transceiver issues.

I would try a different transceiver. Check out the PJRC or skpang breakout boards. The PJRC board was used during the development of TeensyCAN and FlexCAN_T4, never received lockups, skpang board is what I use in the car. Check out what transceivers they use.

The only reason the background callback works is because it is interrupt driven, not controlled via loop. The loop gets stuck on transmit because the error counters increase due to transmittion issue which stops there... but it will not stop the reception interrupt. This is more likely the transceiver issue, try another

And before you ask about it not transmitting but receiving fine, transceivers have this issue when theyre bad or no good. If i find the link ill post it here

EDIT, goto the url on post 172 of this thread (page 7). There is an article which explains your symptoms. Reading, but not transmitting. A transmitter swap to a different model worked.
 
Last edited:
So I found the solution to the bus locking up during TX:
From "Chip Errata for the i.MX RT1060"
https://www.nxp.com/docs/en/nxp/errata/IMXRT1060CE.pdf
ERR005829 - FlexCAN: FlexCAN does not transmit a message that is enabled to be transmitted in a specific moment during the arbitration process.

I was able to successfully apply the suggested workaround by reserving the first TX mailbox and setting this reserved mailbox's CODE = TX_INACTIVE twice immediately after writeTxMailbox().

After applying the bus lockup fix, I still occasionally was getting 2 messages out of sequence.
When writing sequential messages from an interrupt driven callback, it appears possible for the newest message to be transmitted before .events() has had an opportunity to write the next queued message. I think this happens if timing is just right, such that the previous TX message completes transmission leaving the mailbox as TX_INACTIVE.

I was able to workaround this by adding the new message to queue if the queue isn't empty. Would it be more efficient to use a MB interrupt to send the next queued message rather than waiting for events()?
 
By doing this your toggling the transmit mailbox so it may or not may work during transmit and still have issues. These symptoms are not seen with proper transmitters, or with toggling the abort feature. That errata has been around forever since Teensy 3.2. Most of the erratas are copy pasted in NXP documents. This double abort also hinders the performance of the software for every transmission and you loose a mailbox in the process. Like I said if TeensyCAN can transfer 2kbytes of data over canbus with crc validation on reassembly with current library, there is no need to start modifying the library. This is a bad transceiver and once you change it you won't have issues. Considering TeensyCAN transmits in BURSTS, successfully, prooves that there are no transmit issues. Likely the transmitter you are using is either bad OR has bad timing characteristics. Not all transceivers work on all controllers, and there are many forums (not just this one) regarding the issue you are having, that in the end, they changed the transmitter and then it started working properly. Probably the cheaper quality transmitters have bad timing tables that are incompatible, but it does not explain why the pjrc and skpang boards running proper transceivers work perfectly while your transceiver does not and requires a hack to jump start sends which not only hinders the performance of the library for each transmission on everyone's hardware, but loose a mailbox in the process. That errata has been around forever and it is just that, an errata with a "workaround", not a "fix". IFCT & FlexCAN_T4 handles the mailboxes properly EVEN if the first mailbox MB0 is RX. Rather than hacking the library with a workaround, check the many sites off google that speak of transmitters not writing, stalling, but reading fine. It is the transmitter :)

I'd like to have one of these cheap transceivers to test the timing issues they have, there been reports of some work some don't and some work for awhile then stop. I would suggest if you wanna dive into this issue of persisting on keeping that transceiver, check the timing registers of transceiver section in flexcan and see if you can tweak it to different values to see if it'll kick on or not. But if there is an actual transceiver issue, you'll be wasting your time.

Since the errata hasnt affected the library since IFCT days, I doubt a performance penalty mod on a lost mailbox would be required. The only reason why these libraries worked for over 2 years is because they're properly handling the mailboxes, and TeensyCAN/Canquitto would have never ever functioned, ever.
 
If you are suggestion running transmits in an interrupt it is possible, but the ISR handler would need to handle that whenever a transmit interrupt occurs. Yes this is possible but at the same time your still blasting frames. The out of order issue is because your using a workaround which has been around for ages that has never changed in description or silicon yet with a proper transceiver this wouldn't happen.

The interrupt side of transmits can be possible, and enableMBInterrupt() would need to have that feature enabled to work as well, but also events() would need to NOT transmit while the sequential transmits are being sent by interrupt. Essentially going this route would leave the callback events() for RX only. The other thing is, only the first absolute TX mailbox can sent sequential frames in order. We can't enable interrupts for others else they would dequeue and send there unless for each-interrupt that occurs it checks the absolute first TX mailbox everytime for clearance and drop it there. Theres lots of corners we need to consider when we add more features, at the cost of complexity and performance penalty. There is also a consideration of whether we should queue normal transmits and not just sequential. In that case, mailbox redirections need to be considered as well, in both events() and ISR, and to prevent collissions between both.

But crippling a mailbox and adding extra calls isn't likely going to happen as an errata has suggested for years, despite never fixing it in a silicon, that has gone unaffected with current teensy 3.x+ hardware using good transceivers. I believe the workaround is for problematic transceivers that had instability issues with the timing of the hardware. Thats why I suggest instead of trying to fix it by resetting mailboxes every transmit cycle and loosing a mailbox, to look into the transceiver timing tables in flexcan register in datasheet and play with those settings. I can't guarentee that will end up working but it's something I'd check rather than the method your trying
 
I appreciate the insight. I certainly agree with not reducing library functionality to workaround what seems to be only my problem.

I ordered some MCP2562-E/SN and MCP2558FD-H/SN transceivers used on skpang's and PJRC's boards, respectively. I also ordered the ones NXP uses on the 1060 i.MX RT1060 EVK for good measure.

In the mean time, I've tried with no success (granted the 2nd and 3rd are definitely cheap):
TI TCAN330GD (original)
Microchip MCP2551-I/SN
TI SN65HVD232D

I have no allegiance to any of these transceivers, I just tend to lean towards the TCAN330 because it is TI's only 5Mbps chip with FD support. I suppose I'll see how the fancier chips do next week. Thanks for your help!
 
It's probably timing characteristics of the tranceivers. Never had to dwelve into that field using stock settings. However, in CANFD, some bitrates in the calculations are able to modify the transceiver timings.

Granted those timings are for FD end, there is nothing changing on 2.0 end in previous libraries either. Keep in mind there is bitrate switching on CANFD so the tranceiver has to be inlined with the switch when transmitting. By the way, T4 was tested at 1mbit nominal, 8mbps data in CANFD mode on both skpang and pjrc boards, and skpang was able to transfer image data from one T4 to another T4 at those speeds :)

In any case once you get it working with the good tranceivers ill prolly buy the one you have and you can ship it to me so i have it as a confirmed non working transceiver that i can play with here, so i can poke around with it's timings
 
Last edited:
I have a problem that I don't understand....data reading is delayed and not in real time and often loses frames

I must read 5 standard canIDs from my car.
for example:
one of these is the throttle position transmitted every 20ms.
when I press the pedal i can see the results late (about 1-2 seconds) and not smooth.

NOTE: the same data read with an Arduino Nano and a MCP2515+MCP2551 shield are read in real time and with a good smooth :(

i have tried 2 configurations:
First, T4 with a SN65HVD230 transceiver, and after reading this thread, i tried with a 2nd: T4 with a MCP2562FD transceiver, but with the same results as above.
I have tried FIFO and MB filters but nothing.
Code:
#include <FlexCAN_T4.h>.       // [COLOR="#FF0000"]last available version[/COLOR]  
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can0;

void setup(void) {
  Serial.begin(115200);
  while (!Serial) ;
        
  Can0.begin();
  Can0.setBaudRate(500000);
  Can0.setMaxMB(16);

  Can0.setClock(CLK_60MHz);     // [COLOR="#FF0000"]with or without is the same[/COLOR]  

  Can0.distribute();                    // [COLOR="#FF0000"]change a bit but nothing[/COLOR]     

  /*  MB filters  *                       // [COLOR="#FF0000"]MB filters version[/COLOR]  
  Can0.enableMBInterrupts(); 
  Can0.onReceive(canSniff);
 
  Can0.setMBFilter(REJECT_ALL); 
  
  Can0.setMBFilter(0, 0x100);   // transmitted every 10ms (Speed)
  Can0.setMBFilter(1, 0x101);   // transmitted every 20ms (RPM)
  Can0.setMBFilter(2, 0x102);   // transmitted every 20ms (Throttle pos)
  Can0.setMBFilter(3, 0x103);   // transmitted every 100ms (ECT)
  Can0.setMBFilter(4, 0x104);   // transmitted every 20ms (Gear)
*/

  /*  FIFO filters  */                       // [COLOR="#FF0000"]FIFO filters version[/COLOR]  
  Can0.enableFIFO();
  Can0.enableFIFOInterrupt(); 
  Can0.onReceive(FIFO, canSniff);

  Can0.setFIFOFilter(REJECT_ALL); 

  Can0.setFIFOFilter(0, 0x100, STD);
  Can0.setFIFOFilter(1, 0x101, STD);
  Can0.setFIFOFilter(2, 0x102, STD);
  Can0.setFIFOFilter(3, 0x103, STD);
  Can0.setFIFOFilter(4, 0x104, STD);

  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(millis());
  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();

  delay(20);  // [COLOR="#FF0000"]this simulates the time to show data on screen (BT816 GPU)[/COLOR]  
}

What can I try? :confused:
 
That doesn't make sense. When I decrypted my door locks, heated seats, and climate controls, the bits in the frame was toggled immediately with live screen refreshes, I was able to see it toggle as I tapped the locks or hvac buttons in real time, and do a replay to confirm. Are you sure your on the latest release from github?

What happens when the loop delay is removed (shouldn't make a difference)? 1 second responses sounds way off...

Have you also tried without the filters just to see a difference in the stream?

You can also use range based filtering since your IDs are grouped without gaps: Can0.setMBFilter(MB0, 0x100,0x104);
There will be bleed thru frames (0x105 for example), enhancements can filter those out from what your expecting.

I'd refrain from using filters or excess features while debugging, strip it down to basic and check out what happens.
 
Last edited:
i have your last version.

Without delay(20).....it's OK.

i noticed this:
- without delay(20), I can read all data (with or without filters) in real time....perfect.

- with delay(20), I loose data or delay the time to read, but I can see that when I turn off the car, without delay(20) the data reading stop immediately in serial monitor, while with the delay(20) I can still see the data for about 1-2 seconds in serial monitor.
 
Can you copy your callback but rename the new one to

"ext_output1"

And disable events() in loop

Let me know results
 
OK Tony....thanks for your time!

I will try tomorrow.

I'm not working in this weeks for this cursed covid-19 and stay at home all day and I found this pastime.
 
I am using this code between 2 T4's using CAN3 in legacy mode, both on PJRC boards. I output the millisec between each frame and I just change the rates of the other T4 sender

If I send frames at 200ms intervals from one T4 i see them captured at the other T4 at 200ms give or take. If I run it as 0 for constant sending, it still shows ~ 0ms for reception of frames

Am I looking at it wrong ? Because it seems to be working here, unless theres something I am not looking at right.

Sketch for both T4's:
Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> Can0;

void setup(void) {
  Serial.begin(115200); delay(400);
  pinMode(6, OUTPUT); digitalWrite(6, LOW); /* optional tranceiver enable pin */
  Can0.begin();
  Can0.setBaudRate(1000000);
  Can0.setMaxMB(16);
  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();
  static uint32_t _time = millis();
  Serial.print("Time between frames: ");
  Serial.println(millis() - _time);
    _time = millis();
}

void loop() {
  Can0.events();

  static uint32_t timeout = millis();
  if ( millis() - timeout > 200 ) { [COLOR="#FF0000"][B]// change the sender time here[/B][/COLOR]
    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:
MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 63101 ID: 49A Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 2210 ID: 412 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 6050 ID: 25D Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 10315 ID: 245 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 14691 ID: 2E8 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 19245 ID: 73A Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 23626 ID: 745 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 27618 ID: 5E7 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 31936 ID: 733 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 36123 ID: 3D7 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 40516 ID: 332 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 44752 ID: 17 Buffer: 1 2 3 4 5 6 7 8 

Time between frames: 201
 
Last edited:
This may be better to check ID and datafields:

Code:
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> Can0;

void setup(void) {
  Serial.begin(115200); delay(400);
  pinMode(6, OUTPUT); digitalWrite(6, LOW); /* optional tranceiver enable pin */
  Can0.begin();
  Can0.setBaudRate(1000000);
  Can0.setMaxMB(16);
  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();
  static uint32_t _time = millis();
  Serial.print("Time between frames: ");
  Serial.println(millis() - _time);
  _time = millis();
}

void loop() {
  Can0.events();

  static uint32_t timeout = millis();
  if ( millis() - timeout > 2 ) {
    static CAN_message_t msg;
    msg.id++;
    if ( msg.id > 0x7FE ) msg.id = 0x1;
    static int16_t val = -1;
    val++;
    if ( val > 7 ) val = 0;
    for ( uint8_t i = 0; i < 8; i++ ) msg.buf[i] = val;
    Can0.write(msg);
    timeout = millis();
  }

}

I modified the sender to do incremental ID and data.

Here is the log of the slave running same code (notice the 2 ms transmissions the sender is sending at. Also account for the Serial.print 1ms trail resulting in 3ms receptions of correct ID and data incrementations:

Code:
Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 31483 ID: 708 Buffer: 5 5 5 5 5 5 5 5 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 34483 ID: 709 Buffer: 6 6 6 6 6 6 6 6 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 37483 ID: 70A Buffer: 7 7 7 7 7 7 7 7 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 40483 ID: 70B Buffer: 0 0 0 0 0 0 0 0 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 43482 ID: 70C Buffer: 1 1 1 1 1 1 1 1 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 46482 ID: 70D Buffer: 2 2 2 2 2 2 2 2 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 49482 ID: 70E Buffer: 3 3 3 3 3 3 3 3 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 52482 ID: 70F Buffer: 4 4 4 4 4 4 4 4 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 55482 ID: 710 Buffer: 5 5 5 5 5 5 5 5 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 58482 ID: 711 Buffer: 6 6 6 6 6 6 6 6 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 61482 ID: 712 Buffer: 7 7 7 7 7 7 7 7 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 64481 ID: 713 Buffer: 0 0 0 0 0 0 0 0 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 1945 ID: 714 Buffer: 1 1 1 1 1 1 1 1 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 4945 ID: 715 Buffer: 2 2 2 2 2 2 2 2 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 7945 ID: 716 Buffer: 3 3 3 3 3 3 3 3 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 10944 ID: 717 Buffer: 4 4 4 4 4 4 4 4 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 13944 ID: 718 Buffer: 5 5 5 5 5 5 5 5 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 16944 ID: 719 Buffer: 6 6 6 6 6 6 6 6 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 19944 ID: 71A Buffer: 7 7 7 7 7 7 7 7 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 22944 ID: 71B Buffer: 0 0 0 0 0 0 0 0 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 25944 ID: 71C Buffer: 1 1 1 1 1 1 1 1 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 28944 ID: 71D Buffer: 2 2 2 2 2 2 2 2 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 31943 ID: 71E Buffer: 3 3 3 3 3 3 3 3 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 34943 ID: 71F Buffer: 4 4 4 4 4 4 4 4 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 37943 ID: 720 Buffer: 5 5 5 5 5 5 5 5 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 40943 ID: 721 Buffer: 6 6 6 6 6 6 6 6 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 43943 ID: 722 Buffer: 7 7 7 7 7 7 7 7 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 46943 ID: 723 Buffer: 0 0 0 0 0 0 0 0 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 49943 ID: 724 Buffer: 1 1 1 1 1 1 1 1 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 52942 ID: 725 Buffer: 2 2 2 2 2 2 2 2 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 55942 ID: 726 Buffer: 3 3 3 3 3 3 3 3 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 58942 ID: 727 Buffer: 4 4 4 4 4 4 4 4 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 61942 ID: 728 Buffer: 5 5 5 5 5 5 5 5 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 64942 ID: 729 Buffer: 6 6 6 6 6 6 6 6 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 2406 ID: 72A Buffer: 7 7 7 7 7 7 7 7 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 5406 ID: 72B Buffer: 0 0 0 0 0 0 0 0 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 8405 ID: 72C Buffer: 1 1 1 1 1 1 1 1 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 11405 ID: 72D Buffer: 2 2 2 2 2 2 2 2 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 14405 ID: 72E Buffer: 3 3 3 3 3 3 3 3 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 17405 ID: 72F Buffer: 4 4 4 4 4 4 4 4 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 20405 ID: 730 Buffer: 5 5 5 5 5 5 5 5 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 23405 ID: 731 Buffer: 6 6 6 6 6 6 6 6 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 26405 ID: 732 Buffer: 7 7 7 7 7 7 7 7 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 29404 ID: 733 Buffer: 0 0 0 0 0 0 0 0 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 32404 ID: 734 Buffer: 1 1 1 1 1 1 1 1 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 35404 ID: 735 Buffer: 2 2 2 2 2 2 2 2 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 38404 ID: 736 Buffer: 3 3 3 3 3 3 3 3 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 41404 ID: 737 Buffer: 4 4 4 4 4 4 4 4 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 44404 ID: 738 Buffer: 5 5 5 5 5 5 5 5 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 47404 ID: 739 Buffer: 6 6 6 6 6 6 6 6 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 50403 ID: 73A Buffer: 7 7 7 7 7 7 7 7 

Time between frames: 3

MB 99  OVERRUN: 0  LEN: 8 EXT: 0 TS: 53403 ID: 73B Buffer: 0 0 0 0 0 0 0 0

Despite the 2ms transfers and lack of sequential writes, you can see it's not even hiccuping at those rates or receiving in mixed order
EDIT, I noticed you are using 500Kbps, so I tested that too, still runs fine.
EDIT2, I am on Teensyduino loader 1.49 and Arduino 1.8.9
 
Back
Top