Automotive and Embedded Networks

cancel
Showing results for 
Search instead for 
Did you mean: 

What is the most Frames Per Second NI-CAN can do?

My goal is to send 1000 Frames per Second on my CAN bus using the NI-CAN PCI 2 slot card I have.  However the closest I have been able to do is 666 frames per second.  This is sending 8 frames every 12 MS using an edited readmult example.  Is there a way to do this with writemult?  Or is there a hardware limit that I am trying to go past?
 
What can I mess with to get more frames?  Increase Baudrate?  Decrease the size of the frames?  (I've tried both of those)
 
 
 
Other questions that should probably go in other posts  (Frame API):
 
Is there a way to send/read the frames at the bit-level?  I have found ways to manipulate Arbitration ID, Remote Frame, Data Length, and Data, but there are several other bits in a frame.
 
Is there a way to send a bad frame, one that would raise/cause an error frame?
0 Kudos
Message 1 of 6
(6,733 Views)
What baud rate are you using? How many bytes are you sending per frame? At 1MB, the bit time is ~1us. A frame with no data bytes is ~50 bits. A frame with 8 data bytes is ~115 bits. Between frames you must have >= 11 bit times of idle. Therefore, the fastest that 2 frames could be sent back to back at 1MB is approximately 60-130us.

If you are running at 125k, the times will multiply by 8 (baud rate is 8x slower). Therefore, the frame time is approx 0.5-1.1ms. This is all theoretical maximums. There is probably some software overhead that will prevent you from transferring at 100% busload.

If your goal is to send 1000 frames/second, you want to transmit at 1 frame per 1ms. You will be hard pressed to do this at 125k, but you should be able to achieve this at 1MB if your program is written correctly.

Assuming you are using a queue interface to your CAN card, the most efficient the driver will be is if the queue never gets empty. This allows the driver to transmit the next frame immediately (relatively speaking) after the prior one is transferred. Your best programming philosophy would be to pump as many frames as you can into the driver and keep the queues as full as possible. You can write up to 512 frames with each WriteMult call and you can check the state to make sure that the WriteMult state is true, meaning that you can fit another 512 frames into the queue. You would keep queueing up frames until the queue is full (or you run out of data to send) in this manner.


I don't believe there are any ways to inject bit errors into the frame using NI-CAN. You only have access to the user-defined fields of the frame as you listed.
Message 2 of 6
(6,731 Views)
Thanks that helps.
 
250 kbps is my goal, though I could use a baud rate of 125, 250, 500, or 1 Mbps.
 
I forgot about the 11 bits of idle time, thanks for the reminder, but I was working under the assumption that the worst case 8 data byte would be ~160 bits (Extended 8 byte frame starting with 11111 or 00000 and every 4 bits afterwards alternating), because of bit stuffing.  So I was trying for 160000 bits delivered per second, adding the 11 bits idle, 171000.  Obviously 125 isn't enough, but there is still room left in 250 kbps.
 
I'm using Standard frames so I won't hit that worst case.
 
Thanks for the maximum queue length, I think that saved me a headache.
 
If I try to go too fast, I get an error that looks like this:  NI-CAN:  (Hex 0xBFF620A1) Too many messages with high transmit rates.  The combined timers cannot be accurately maintained.
 
There were a couple of others that were similar I found too.  I'm wondering what the function it uses to determine it is too fast.  What is the limit?
 
 
As for bit injection:  Dang.  Is there a way to test/check CAN Error detection?
0 Kudos
Message 3 of 6
(6,710 Views)
Hey Jakerlton,

The cause of this error you are receiving (Hex 0xBFF620A1) is because you are trying to use the channel api and send to many messages at a specified rate. The driver uses a formula that takes the update rate, number of messages, bus speed, and message size into account in order to calculate if the bus can sustain that rate.  To get rid of this error just need lower your update rate.

Also, what software are you using for your application? 

Regards,

Jason W
Application Engineer
National Instruments
0 Kudos
Message 4 of 6
(6,690 Views)

Hi! I found this thread and i would like to ask you if you could get any closer to 1000frames, cause i have the same problem.

I am trying to get higher but i am stucked at around 650/s, and still couldnt find any solution for sending more frames.

If you solved this problem pls let me know the details of your trick! 🙂

Thx in advance!

Gábor

0 Kudos
Message 5 of 6
(6,540 Views)

Yes, I did break 1,000 Frames Per Second.  I got up to 1,714 and 1,742 using two different methods.  This is at 250 kbps, if you used 500 or 1 Mbps, you could get more frames.  If you have 125 kbps, you might not be able to break 1,000 Frames per Second.

 

ncWriteMult is the key.  You can load 512 frames in a queue at a time.  I would put 256 on at a time and check to see if there was less than 256 frames left in the queue and if there was, load it up, that way the queue would never be empty.  I went about it 2 ways, one was using ncGetAttribute to determine space left, and that got the faster method, however, I was also trying to read the messages to verify that it worked, and I had problems with logging every frame.  It would also send the first 40 ncWriteMults quickly, as if the queue it was filling was much larger than 512.

 

The other way, was using trial and error to determine how many MS to sleep before writing the next batch of 256 frames.  There are variables outside of my control that determined the time it would take and it would vary a few ms.  I wanted a stable environment that could send forever without filling the queue so I went with a value that would wait 2 or 3 ms, depending on conditions before writing again.  The value I used was 142 ms, I think.  Your Mileage May Vary.

 

There is also a way to do some error handling that I did not try to utilize.  Instead of the process crashing, there is a way to tell it to wait if this error is returned.  That might be the best way for me to implement what I wanted to do, but I was assigned another task before I tried to get that to work.

 

There is a timing element in ncWriteMult's documentation I didn't look into very much, but that would space the frames out and could send 1,000 frames a second evenly distributed, instead of sending them as quickly as possible, wait some ms then send another batch.

 

If anyone could link us, or provide some code snippets of the error handling, or proper usage of ncGetAttribue, or some way to read faster, that would be greatly appreciated.

 

0 Kudos
Message 6 of 6
(6,533 Views)