FezDuino (SC20100) - CAN WriteMessages Exception

Hello,

I have a problem with sending several messages on the CAN bus. Sending goes well if the array does not exceed 16 messages. Beyond that I get an exception. Below is an extract of the code used and the result obtained :

I’m using a TCAN1051HD transceiver and my CAN bus is wired very short with two 120Ohm terminators.

If I disconnect the CAN transceiver the exception occurs from 6 messages.
I get the same exception with sending a single message via the ‘WriteMessage()’ method if I send too many messages without delay between calls.

Do you have any idea what this could be coming from and how to fix the problem?

Thanks,
Erwan

Does the receiver receive all first 16 msg?

Yes it does :

image

We will take a look, for now, can you try to delay a bit between two sending msg?

Yes that’s what I do.
I use Thread.Sleep(1) between sending messages and it works.

does it work for all messages or just first 16 messages?

It works for all messages.
I send up to 20 messages in a row when I send fastpacket messages using NMEA2000.

Not sure if it helps for now. You can send 15 messages than sleep (1)

Something like

if (sendCounter % 15 == 0) sleep(1)

We will check the fifo later.

Yes, that’s what I did to temporarily resolve the issue.

Hi, it is not a bug.
Before you send a message, you should check controller.CanWriteMessage make sure it is true.
Here you checked controller.CanWriteMessage then you send an array 16 messages. This is not how controller.CanWriteMessage work.
controller.CanWriteMessage is valid for next one message only, it is not guaranty for next 2,3 or 100 messages.
There are 16 messages in fifo internally, so the exception “Busy” is correct and system works as we expected.

You don’t need to delay, need check controller.CanWriteMessage before send a next message.
Let us know if you have any other questions.

Hi,

Thanks for your answer.

I understand your explanation when I use controller.WriteMessage() method. That’s exactly what I do.
But what should I do if controller.CanWriteMessage is not valid before sending a message ? I need to delay no ? How long ?

In my code I use controller.WriteMessages() to send multiples messages in a single instruction. And in this case I can only check the boolean controller.CanWriteMessage once. In my attached example I add a for loop to demonstrate that the bug appears from 16 messages. In my application I need to send 20 messages as quickly as possible.

Would this mean that this method cannot be used beyond 16 messages?

The fast and safe way is, check and send every single message.

But what should I do if controller.CanWriteMessage is not valid before sending a message

You need to wait until valid. No choice. It will be valid as soon as there is at least one tx fifo ready. There is 16 fifo so it will be quick.

I need to delay no ?

You don’t need to delay, pull controller.CanWriteMessage until true then you can write, although I always recommend delay 1ms at least, if pulling from a thread and there is multi threads are running.

How long ?

We can calculate how fast a message will be sent, but no way to know when the system will send the message internally, so no way to answer “How long”.

Without pulling CanWriteMessage , sleep 1ms may work with at this time but after changing your code with larger project may not work. Pull CanWriteMessage before every single message still highly recommended,

yes, no more than 16 messages for now. You can check & send single message without delay, no matter how many messages you write from C#, internal FIFO is still 16, the speed won’t be different.

I think below is the best for your case.

while (true) {
 if (sendCounter % 20 == 0) sleep(1) 

 if (controller.CanWriteMessage) {
      controller.WriteMesage(.....)
      sendCounter ++;
  }
}