Abstract
In this application note we will demonstrate how to use RawCAN to send and receive custom CAN frames between two Roboteq drives. One Roboteq drive will be used as master and the other as slave. The RoboCAN transmit and receive process, will be implemented using microbasic scripting language.
RawCAN Frame
RawCAN uses the following frame to transmit data bytes:
- Byte 0: Represents the ID of the receiver. The receiver uses this ID to determine whether the packet is addressed to it.
- Byte 1: This is the number of bits included in the packet. It is used by the receiver to determine how many of the frame it will read
- Bytes 2 to 9: These are the bytes of the information that will be sent.
Transmit and Receive Process
The master transmits the required frame. Each slave on the bus receives the frame and must mask the first byte to determine whether the packet is addressed to it. If the ID matches, the slave reads the second byte to determine the number of data bytes, and then proceeds to read the remaining bytes accordingly.
Using the MicroBasic Language
Microbasic uses the following commands to send and receive RawCAN frames:
Send RawCAN frames
Setcommand(_CSS, cc, nn)
Where:
- cc = Byte to send
- 1 = Node ID
- 2 = Number of Bytes
- 3 to 10 = Payload bytes
- nn = Value to write
Note: The frame is transmitted when the "Number of Bytes" byte is written. Therefore, this byte must be written last by the master.
Checking Pending number of bytes
The following command will return the number of frames pending to the 16-frame FIFO buffer, and copy the oldest frame to the read buffer.
Getvalue(_CF,1)
Receive RawCAN frames
Getvalue(_CAN,cc)
Where:
- cc = Number of bytes to read
- 1 = ID
- 2 = Bytes Count
- 3 to 9 = Data 0 to Data 7
Script Examples
The following script example runs on the master and sends values for the Position and Speed commands. These values are segmented into bytes by shifting the command data and masking with 0xFF.
The script follows:
'Transmitter Script
option explicit
dim PositionCommand as integer
dim SpeedCommand as integer
dim sendBytes [10] as integer 'the table to send the command
PositionCommand = 1234567890 ' Example value for Position command
SpeedCommand = 987654321 ' Example value for Speed command
'Position and Speed command bytes are being shifted to fit in the sendBytes frame
sendBytes[2] = (PositionCommand >> 24) and 0xFF ' Most significant byte of PositionCommand
sendBytes[3] = (PositionCommand >> 16) and 0xFF
sendBytes[4] = (PositionCommand >> 8) and 0xFF
sendBytes[5] = PositionCommand and 0xFF
sendBytes[6] = (SpeedCommand >> 24) and 0xFF ' Most significant byte
sendBytes[7] = (SpeedCommand >> 16) and 0xFF
sendBytes[8] = (SpeedCommand >> 8) and 0xFF
sendBytes[9] = SpeedCommand and 0xFF
sendbytes[0] = 0x1F 'ID of the frame
sendbytes[1] = 8 'Number of Data bytes. After this bit is set, the frame will be sent.
On the slave side, the following script checks for pending frames. If the ID matches the node's address, it reads each byte and reconstructs the Position and Speed variables by shifting and adding the bytes.
'Receiver Script
Option Explicit
dim PositionCommand as integer
dim SpeedCommand as integer
if getvalue(_CS)>0 'Check if there are incoming frames
if getvalue(_CAN,0) = 0x1F 'Check the frame ID to see if it is addressed to this node
PositionCommand = (getvalue(_CAN,2) << 24) + (getvalue(_CAN,3) << 16) + (getvalue(_CAN,4) << 8) + getvalue(_CAN,5)
print(PositionCommand,"\n")
SpeedCommand = (getvalue(_CAN,6) << 24) + (getvalue(_CAN,7) << 16) + (getvalue(_CAN,8) << 8) + getvalue(_CAN,9)
print(SpeedCommand)
end if
end if