Automotive and Embedded Networks

cancel
Showing results for 
Search instead for 
Did you mean: 

How to send more than 8 bytes by using Ni-API?

Hi,

We have a device which uses CANbus to communicate, but this device needs more than 8 bytes data to control motors. Usually we can only send 8 bytes for each frame, we can't just simply send twice.
Does anyone do this before?

Thanks for your reply,
James
0 Kudos
Message 1 of 9
(7,858 Views)
You can't send more than 8 bytes at a time. Look at page 1-1 of the NI CAN hardware and software manual. This is not just a NI limitation, all the major CAN protocols specify a maximum of 8 data bytes.

You need to research your can specification or standards body. Exactly what kind of device is it, and do you know if it is defined in a CAN protocol?

Usually the devices will need to send 2 frames for more than 8 data bytes, for example, you may see frames like these below.
0x700:00 11 22 33 44 55 66 77
0x701:88 99 AA BB

or frames like this below, which have a byte reserved for sequence number:
0x1CABCD00:01 00 11 22 33 44 55 66
0x1CABCD00:02 77 88 99 AA BB

occasionally the frames will be in a command response, meaning they are only sent if re
quested:
0x200 00 07 00 (your NI card sends request for a frame)
0x700:00 11 22 33 44 55 66 77 (the device responds with first frame)
0x201 00 07 01 (your NI card requests the second frame)
0x701:88 99 AA BB (the device responds with second frame)

THESE ARE JUST EXAMPLES, CHECK YOUR OWN DATA FOR CORRECT FRAME ID'S!

So the question is EXACTLY what device are you using, and what CAN protocol does it use?
Message 2 of 9
(7,858 Views)
Hi, dhuff:

Thanks a lot!

The device is called Collimator, which is for vCT machine and adjust the X-ray path. it uses CAN extended specification.

There are 3 step motors need to be controlled, and the parameters are more than 8 bytes. THIS IS THE REAL PROBLEM HERE! colllimator uses 29 bits as arbitration ID, there are a few bits for SEQ_FRAME, FRAME_RESP, FRAME_CTRL among the ID, it is complicated though, All of them have different cases, we have to figure out how to set those bits for different messages, the docs are not very direct, we have to dig into the source codes we have, it is very bitter.

It looks like the device is the first case by increasing the seq_frame. But for each frame, we have to sent ack back to the sender, if not good, se
nt it again automatically.

on the collimator side, there are a few tasks under RTOS (VxWorks) dedicated for the CAN message transfer,
and use Interrupt Service Routine, for combining data from 2 or more CAN frames. this makes life difficult.

My question is: how do we do the same thing (ISR) by using NI-CAN card and API under Win2K?
We can't just simply wait for all frames complete,
do we have to put another layer above NI-API?

Your reply will be appreciated!

James
0 Kudos
Message 3 of 9
(7,858 Views)
You will need to develop a VI that periodically listens for CAN traffic received at the NI card, and responds with the correct transmitted CAN based on the recieved CAN messages. I think the NI CAN cards are fast enough that you don't need to mess with ISR's or other stuff.
0 Kudos
Message 4 of 9
(7,858 Views)
Since we don't have LabView and can't use ISR either, the only way is to use one thread (in VC++) to listen CAN traffic, but we can't just create CAN Object and using callback function, because the Arbitration ID keeps changing, for example, the ID for first CAN packet is 0x01234567, the ID for the next packet is 0x01234568 or othe numbers. actually there are 3 bits finside the 29 bit ID used for sequence packet, this is how the device (collimator) works.

Is there any other way to listen the CAN traffic? by keeping ncRead in a infinite loop?

Thank you,

James
0 Kudos
Message 5 of 9
(7,858 Views)
Basically, you want to do a POLLED read
1. Create a main thread that configures the whole system and will run until you stop it (a while loop for example)
2. Initialize the CAN port to read and write 29 bit ID's, and hold onto that thread
3. In your main thread check to see if there are CAN messages to read using the CAN thread (ncGetProperty will probably tell you if messages are waiting). If there are messages to read, read them and decide if it is a message you need to respond to.
4. If you need to respond, format your CAN message and send it using a write function. If it is not a message you need, ignore it and move on

I use Labview and CVI to write my code, so I am afraid I can't be more specific, I have never used VC
++.
0 Kudos
Message 6 of 9
(7,858 Views)
Thanks again, nctGetProperty is for Channel API, we are using Frame API, using ncWaitforState may not a good idea, and we can't use Chaneel API and Frame API at the same time.
do I have to use Channel API?

James
0 Kudos
Message 7 of 9
(7,858 Views)
The fact is, there are many different ways to do this, my intent by the previous post is give a general example of a polled read. I can think of at least 3 or 4 different ways I have done it, depending on what the specific task is.
I like to stick with 1 approach, simply because it works for me. Some people like using all frame API's and others just use channel API's, it is really up to whatever works for you. I like to use all frame API's because I understand them, and they are more flexible.

You should also take a look at ncReadMulti function, I have found that it is usually easier to use than the simple read. I usually use ncReadMulti and look at the number ACTUALDATASIZE returned to me, it will be 0 if
I do a read with no messages available, and it will NOT return an error like the ncRead for an empty queue. The readmulti also eliminates the need for a ncWaitForState, I just call the read, and look at the number of frames returned. If there is more than 1 message returned, I just use a for loop to look at all the frames, and ignore the ones I don't need.
0 Kudos
Message 8 of 9
(7,858 Views)
thanks,

for the device we are using, it will not send the second frame without ACK from other side,so we even can use ncRead to do that. the only thrick is listening to CAN traffic reliably and response some "ACK" immediately (different CANObjects).

Jame
0 Kudos
Message 9 of 9
(7,858 Views)