Using DINRail SE410S-X10 as CAN FD translator

  • October 26, 2021
  • Lars-Göran Fredriksson

In this document I will show how to use a Kvaser DINRail as a CAN FD to CAN translator. I will use a database with defined signals and show how to use them in a t-program. The new Kvaser DIN Rail SE410S-X10 allows a standalone CAN translation unit to be created that does not need an additional computer to run.

All information and tools needed to follow this document are license free and can be found on our homepage www.kvaser.com.

All code samples and models mentioned in this document are free to use. 

Any Kvaser multi-channel devices with t programming capability can be used for testing and debugging. I will use the “Kvaser DIN Rail SE410S-X10”.

Please feel free to contact us if you have any questions about this document. Just send questions or comments to : [email protected]

Field Application Engineer, Kvaser AB

Lars-Göran Fredriksson

[email protected]

1 The test model

I do not have a physical network to play around with, so I need to create one. I have decided to have one CAN FD network and one standard CAN network:

I must admit, this is a very beautiful picture. What I try to illustrate are two well-terminated CAN-bus, connected to a DINRail SE410 interface.

1.1 My CAN FD network

On my FD network (the one connected to channel 1 and 2) is a magical device that sends and receives the message TEST_MSG_101. It is a CAN FD frame with the ID 101 and contains eight different signals: Latitude, Longitude, Altitude, Speed over ground, Course over ground, Roll, Pitch and Heading. These are typical values that might come from a combined GPS/Gyro sensor.

1.2 My (standard) CAN network

On my standard CAN network (the one connected to channel 3 and 4), I have three magical devices that send and receive the messages TEST_MSG_201, TEST_MSG_202 and TEST_MSG_203.  

The first message handles the signals Roll, Pitch and Heading. The second handles Latitude, Longitude and Altitude. The third handles Speed over ground and Course over ground.

(Please check Appendix A for a description of the DBC file and the signals)

Why did I invent a non-existent network? Most times when working with DBC files, the communication protocol follows the J1939 standard. J1939 is a standard owned by SAE and I am not allowed to publish any of their protocols or signal id.

On the DINRail I will use channels 1 and 3 for the t-script. Channels 2 and 4 will be used as debugging channels so I can emulate my magical devices. (I will use Kvaser CANKing software to send and receive text messages on channels 2 and 4.)

2 The t-script

(For information on how to use t-script. Please see section 5.4)

(You can find the complete listing for the t-script and DBC file in appendix A and B.)

2.1 Basic Setup

variables {
  const int MyCANFDch=0;
  const int MyCANch=2;
}

on start {
  printf("Script started...\n");

  canBusOff(MyCANFDch);
  canBusOff(MyCANch);

  //Set First channel (FD)
  canSetBitrate(MyCANFDch,canFD_BITRATE_500K_80P);
  canSetBusOutputControl(MyCANFDch, canDRIVER_NORMAL);

  canSetBitrateFd(MyCANFDch,canFD_BITRATE_2M_80P);
  canSetCommunicationMode(MyCANFDch, canMODE_CAN_FD);

  //Set Second channel (STD)
  canSetBitrate(MyCANch,canBITRATE_250K);
  canSetBusOutputControl(MyCANch, canDRIVER_NORMAL);


  canBusOn(MyCANFDch);
  canBusOn(MyCANch);
}

on stop {
  canBusOff(MyCANFDch);
  canBusOff(MyCANch);
printf("Script stopped...\n");
}

This script does almost nothing, except for the most important part, starting up the two CAN channels.
The first channel is set up as a 500kbit/2Mbit CAN FD channel and the second is set up as a 250kbit standard CAN channel.

If we compile and run this script in TRX, we will see that the script starts and stops.
OK, exactly what we wanted, but no magic yet.

2.2 Adding the file DB_FD.DBC

Open the menu: Project, select: Add Database

A dialog box will show and you will be able to add a DBC file to your project.

Important: Make sure that you save your PROJECT. If you use FILE/SAVE then you will only save the t-file. Instead use PROJECT/Save Project As …

2.3 Using DBC messages as variables

When we have added the DBC file to the PROJECT, it is possible for us to create message and signal variables.

One of the defined CAN Messages in the DBC file is:TEST_MSG_101

I will now create a GLOBAL variable (FD_GPS) of this type.
In the BLOCK: Variables {}, add the line:
CanMessageFd_TEST_MSG_101 FD_GPS;

Add the text “CanMessageFD_” to MessageName and TRX will understand that it shall look for it in the DBC file.

variables {
  const int MyCANFDch =0;
  const int MyCANch   =2;

  CanMessageFd_TEST_MSG_101 FD_GPS;


  int FD_GPS_TEST=0;

}

Now I have a global variable to play with. 

2.4 Using DBC messages as identifiers

on CanMessageFd <MyCANFDch> TEST_MSG_101 {
  printf("Detected TEST_MSG_101 :%d\n", this.id);
}

This HOOK will be activated every time there is a message with the ID 101 on the CAN FD bus.

Now comes the magic: we can use the physical values of the signals, without any strange and advanced calculations.

on CanMessageFd <MyCANFDch> TEST_MSG_101 {
  printf("Detected TEST_MSG_101 :%d\n", this.id);

  printf("LAT P:%f\n", this.S_101_LAT.Phys);
  printf("LAT R:%d\n", this.S_101_LAT.Raw);
}

Running the above script, and detecting a “101” message.

We can directly address the data in the SIGNAL S_101_LAT. We can access it as Physical values or Raw values. In the output above we can see that a value of 1800000 is equivalent to 0.000 degrees. (OK, it prints 0.000015, but that is very close to 0.000)

2.5 Adding one CanMessageFd hook

on CanMessageFd <MyCANFDch> TEST_MSG_101 {
  CanMessage_TEST_MSG_201   STD_GPS_RPH;
  CanMessage_TEST_MSG_202   STD_GPS_LatLonAlt;
  CanMessage_TEST_MSG_203   STD_GPS_SogCog;

//  printf("Detected TEST_MSG_101 :%d\n", this.id);
//  printf("LAT P:%f\n", this.S_101_LAT.Phys);
//  printf("LAT R:%d\n", this.S_101_LAT.Raw);

  STD_GPS_RPH.S_201_ROLL.Phys      =this.S_101_ROLL.Phys;
  STD_GPS_RPH.S_201_PITCH.Phys     =this.S_101_PITCH.Phys;
  STD_GPS_RPH.S_201_HEAD.Phys      =this.S_101_HEADING.Phys;
  canWrite(MyCANch,STD_GPS_RPH);
  
  STD_GPS_LatLonAlt.S_202_LAT.Phys =this.S_101_LAT.Phys;
  STD_GPS_LatLonAlt.S_202_LON.Phys =this.S_101_LON.Phys;
  STD_GPS_LatLonAlt.S_202_ALT.Phys =this.S_101_ALT.Phys;
  canWrite(MyCANch,STD_GPS_LatLonAlt);

  STD_GPS_SogCog.S_203_SOG.Phys    =this.S_101_SOG.Phys;
  STD_GPS_SogCog.S_203_COG.Phys    =this.S_101_COG.Phys;
  canWrite(MyCANch,STD_GPS_SogCog);
}

The FD message “101” will be split into three standard CAN messages.

The signals in the 201, 202 and 203 messages have less resolution in their values, but we do not need to worry about that. The t-script will take care of the translation of the logical bits and bytes.

2.6 Adding three CanMessage hooks

on CanMessage <MyCANch> TEST_MSG_201 {

  FD_GPS.S_101_ROLL.Phys    =this.S_201_ROLL.Phys;
  FD_GPS.S_101_PITCH.Phys   =this.S_201_PITCH.Phys;
  FD_GPS.S_101_HEADING.Phys =this.S_201_HEAD.Phys;

  FD_GPS_TEST= (FD_GPS_TEST | 1);  

  if (FD_GPS_TEST>=7) {
    canWrite(MyCANFDch,FD_GPS);
    FD_GPS_TEST=0;
  }
}
on CanMessage <MyCANch> TEST_MSG_202 {

  FD_GPS.S_101_LAT.Phys  =this.S_202_LAT.Phys;
  FD_GPS.S_101_LON.Phys  =this.S_202_LON.Phys;
  FD_GPS.S_101_ALT.Phys  =this.S_202_ALT.Phys;

  FD_GPS_TEST= (FD_GPS_TEST | 2);  

  if (FD_GPS_TEST>=7) {
    canWrite(MyCANFDch,FD_GPS);
    FD_GPS_TEST=0;
  
on CanMessage <MyCANch> TEST_MSG_203 {

  FD_GPS.S_101_COG.Phys  =this.S_203_COG.Phys;
  FD_GPS.S_101_SOG.Phys  =this.S_203_SOG.Phys;

  FD_GPS_TEST= (FD_GPS_TEST | 4);  

  if (FD_GPS_TEST>=7) {
    canWrite(MyCANFDch,FD_GPS);
    FD_GPS_TEST=0;
    FD_GPS_TEST=(FD_GPS_TEST & (1+2+0));
  }
}

We must wait until we get all three messages before we retransmit the “101” message.

3 Storing the t-program in the memory

The Kvaser DIN Rail SE410S-X10 has a battery backed up 16GB non-replaceable memory. It uses the battery to make sure that all uncommitted changes are saved properly before a shutdown.

The memory area can be used for storing local data and t-script. It can be modified via SDK (CANlib), t-script or via the filehandler in Kvaser Device Guide(1)(2).

(1) 2020-12-20 The version with the filehandler is not yet released. Is planned to be released with version 5.36.

(2) If you read this before CANlib SDK 5.36 is released, and want to test the file handler, please send me an email and I will send it to you. ([email protected])

See Appendix C for some detailed memory restrictions

3.1 Autostart t programs

(This information can also be found in the USER GUIDE)

Kvaser DIN Rail SE410S-X10 can automatically load and run up to four t programs from memory at power on. This is done by entering the names of the t programs into a special file, autoexec.txt, and copying the compiled t programs (*.TXE) and AUTOEXEC.TXT to the memory.

To stop the t programs from being started at power on, simply delete AUTOEXEC.TXT from flash storage or edit the AUTOEXEC.TXT file.

3.2 AUTOEXEC.TXT

This is a special text file that Kvaser DIN Rail SE410S-X10 tries to read from flash storage at power on. Each line must have the following format: 

filename, channel, slot 

3.2.1 Filename

Filename is the name of the compiled t program. It has the extension TXE.

3.2.2 Channel

Channel is the CAN channel that the t program will use by default. (We are not using the default channel in our script)

(see Kvaser t Programming Language guide for further details.)

3.2.3 Slot

Slot is one of four slots numbered 0 to 3 that are available for t programs in Kvaser DIN Rail SE410S-X10.

3.3 Our AUTOEXEC.TXT file

I named my t-script: T-DEM-FD.t

Compiled name: T-DEM-FD.TXE

Let us create a file named “autoexec.txt” with the line:

T-DEM-FD.TXE, 0, 0

Start T-DEM-FD, use default channel 0 and start it in slot 0.

4 Conclusion

Using a DBC file in a t program is simple. Handling message ID and signals is much easier when they are defined in a DBC file.

We must still create the logic of how to transfer data and how to convert between different signals, but we do not need to work with raw data.

The t-program does not check for data loss because of differences in precision and range. This must be prepared for when creating the script.

I hope the info in this document will help you. Comments and questions are welcome!

Field Application Engineer, Kvaser AB

Lars-Göran Fredriksson

[email protected]

5 Helpful references and tools

5.1 The fileT-DEMO-FD.t

This is a text file containing the t program code used in this document, please check appendix B for a complete listing.

5.2 The file DB_FD.DBC

Please check Appendix A.

This file contains the messages and signals used in this document.

5.3 Kvaser SDK and Drivers

5.4 The Kvaser t Programming Language

From the user guide:
The Kvaser t programming language is event oriented and modeled after C. It can
be used to customize the behavior of the Kvaser Eagle and other Kvaser t capable
devices.
A t program is invoked via hooks, which are entry points that are executed at the
occurrence of certain events. These events can be, for example, the arrival of
specific CAN messages, timer expiration, or external input.
The addition of t programs running directly on a Kvaser Device makes it possible
to react much quicker to CAN bus events (for example to speed up file transfer
protocols or to simulate missing hardware). Some Kvaser devices can also operate
completely autonomously, e.g. the Kvaser Memorator.

I will not cover the basics of Kvaser t Programming,
please check the user guide: The Kvaser t Programming Language.
https://www.kvaser.com/download/?utm_source=software&utm_ean=7330130980327&utm_status=latest

There is also some Blogs on our homepage:
https://www.kvaser.com/developer_category/t-script/

5.5 The software TRX

Kvaser TRX, a lightweight IDE for developing t programs for supported Kvaser devices.

https://www.kvaser.com/resource/trx-guide/

This software is installed when installing Kvaser SDK.

5.6 The Kvaser Database Editor 3

I will not cover how to create, use and maintain a signal database. Kvaser has a free tool: ”Kvaser Database Editor 3

With this tool you can view, create and edit *.DBC files.

https://www.kvaser.com/download/?utm_source=software&utm_ean=7330130981942&utm_status=latest

We do have some Blogs on our homepage:
https://www.kvaser.com/developer_category/dbc/
https://www.kvaser.com/developer_category/database/

5.7 Kvaser CANKing

A free of charge, general-purpose CAN bus monitor. It works with all CAN interfaces from Kvaser and also with the virtual CAN bus.

https://www.kvaser.com/download/utm_source=software&utm_ean=7330130980686&utm_status=latest

6 Appendix A, the file DB_FD.DBC

Please note that the signals in the CAN FD message (101) have much higher resolution than the signals in the CAN messages (201,202 and 203). The purpose with that is to show that it is easy to convert values of the signals in a t-program. I will not analyze the loss of precision this will create.

6.1 Messages in DB_FD.DBC

6.1.1 TEST_MSG_101

6.1.2 TEST_MSG_201

6.1.3 TEST_MSG_202

6.1.4 TEST_MSG_203

6.2 Database DB_FD.DBC source code

Please copy and paste the information below, to a text file and name it: DB_FD.DBC

VERSION “”
NS_ :
NS_DESC_
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_

BS_:

BU_:

BO_ 3221225472 VECTOR__INDEPENDENT_SIG_MSG: 0 Vector__XXX
SG_ NewSignal_0008 : 0|[email protected]+ (1,0) [0|0] “” Vector__XXX

BO_ 101 TEST_MSG_101: 32 Vector__XXX
SG_ S_101_LAT : 0|[email protected]+ (0.001,-180) [-180|180] “deg” Vector__XXX
SG_ S_101_LON : 32|[email protected]+ (0.001,-180) [-180|180] “deg” Vector__XXX
SG_ S_101_ALT : 64|[email protected]+ (0.001,-1000) [-1000|20000] “m” Vector__XXX
SG_ S_101_SOG : 96|[email protected]+ (0.001,0) [0|1000] “m/s” Vector__XXX
SG_ S_101_COG : 128|[email protected]+ (0.001,0) [0|360] “deg” Vector__XXX
SG_ S_101_ROLL : 160|[email protected]+ (0.001,-180) [-180|180] “deg” Vector__XXX
SG_ S_101_PITCH : 192|[email protected]+ (0.001,-180) [-180|180] “deg” Vector__XXX
SG_ S_101_HEADING : 224|[email protected]+ (0.001,-180) [-180|180] “deg” Vector__XXX

BO_ 201 TEST_MSG_201: 6 Vector__XXX
SG_ S_201_ROLL : 0|[email protected]+ (0.1,-180) [-180|180] “deg” Vector__XXX
SG_ S_201_PITCH : 16|[email protected]+ (0.1,-180) [-180|180] “deg” Vector__XXX
SG_ S_201_HEAD : 32|[email protected]+ (0.1,-180) [-180|180] “deg” Vector__XXX

BO_ 202 TEST_MSG_202: 6 Vector__XXX
SG_ S_202_LAT : 0|[email protected]+ (0.1,-180) [-180|180] “deg” Vector__XXX
SG_ S_202_LON : 16|[email protected]+ (0.1,-180) [-180|180] “deg” Vector__XXX
SG_ S_202_ALT : 32|[email protected]+ (0.1,-1000) [-1000|20000] “m” Vector__XXX

BO_ 203 TEST_MSG_203: 4 Vector__XXX
SG_ S_203_SOG : 0|[email protected]+ (0.1,0) [0|1000] “m/s” Vector__XXX
SG_ S_203_COG : 16|[email protected]+ (0.1,0) [0|360] “deg” Vector__XXX

BA_DEF_ BO_ “CANFD_BRS” ENUM “0”,”1″;
BA_DEF_ “BusType” STRING ;
BA_DEF_ BU_ “ECU” STRING ;
BA_DEF_ BO_ “VFrameFormat” ENUM “StandardCAN”,”ExtendedCAN”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”reserved”,”StandardCAN_FD”,”ExtendedCAN_FD”;
BA_DEF_DEF_ “CANFD_BRS” “1”;
BA_DEF_DEF_ “BusType” “”;
BA_DEF_DEF_ “ECU” “”;
BA_DEF_DEF_ “VFrameFormat” “StandardCAN”;
BA_ “BusType” “CAN FD”;
BA_ “VFrameFormat” BO_ 101 14;
BA_ “VFrameFormat” BO_ 201 0;
BA_ “VFrameFormat” BO_ 202 0;
BA_ “VFrameFormat” BO_ 203 0;

7 Appendix B, the file T-DEMO-FD.t





variables {
  const int MyCANFDch =0;
  const int MyCANch   =2;

  CanMessageFd_TEST_MSG_101 FD_GPS;
  //CanMessage_TEST_MSG_201   STD_GPS_RPH;
  //CanMessage_TEST_MSG_202   STD_GPS_LatLonAlt;
  //CanMessage_TEST_MSG_203   STD_GPS_SogCog;

  int FD_GPS_TEST=0;
  
}

on start {
  printf("Script started...\n");

  canBusOff(MyCANFDch);
  canBusOff(MyCANch);

  //Set First channel (FD)
 
  canSetBitrate(MyCANFDch,canFD_BITRATE_500K_80P); //canSetBitrate(MyCANFDch,canBITRATE_500K);
  canSetBusOutputControl(MyCANFDch, canDRIVER_NORMAL);
  canSetBitrateFd(MyCANFDch,canFD_BITRATE_2M_80P);
  canSetCommunicationMode(MyCANFDch, canMODE_CAN_FD);

  //Set Second channel (STD)
  canSetBitrate(MyCANch,canBITRATE_250K);
  canSetBusOutputControl(MyCANch, canDRIVER_NORMAL);


  canBusOn(MyCANFDch);
  canBusOn(MyCANch);
}

on stop {
  canBusOff(MyCANFDch);
  canBusOff(MyCANch);
  printf("Script stopped...\n");
}

on CanMessageFd <MyCANFDch> TEST_MSG_101 {
  CanMessage_TEST_MSG_201   STD_GPS_RPH;
  CanMessage_TEST_MSG_202   STD_GPS_LatLonAlt;
  CanMessage_TEST_MSG_203   STD_GPS_SogCog;

//  printf("Detected TEST_MSG_101 :%d\n", this.id);
//  printf("LAT P:%f\n", this.S_101_LAT.Phys);
//  printf("LAT R:%d\n", this.S_101_LAT.Raw);

  STD_GPS_RPH.S_201_ROLL.Phys      =this.S_101_ROLL.Phys;
  STD_GPS_RPH.S_201_PITCH.Phys     =this.S_101_PITCH.Phys;
  STD_GPS_RPH.S_201_HEAD.Phys      =this.S_101_HEADING.Phys;
  canWrite(MyCANch,STD_GPS_RPH);
  
  STD_GPS_LatLonAlt.S_202_LAT.Phys =this.S_101_LAT.Phys;
  STD_GPS_LatLonAlt.S_202_LON.Phys =this.S_101_LON.Phys;
  STD_GPS_LatLonAlt.S_202_ALT.Phys =this.S_101_ALT.Phys;
  canWrite(MyCANch,STD_GPS_LatLonAlt);

  STD_GPS_SogCog.S_203_SOG.Phys    =this.S_101_SOG.Phys;
  STD_GPS_SogCog.S_203_COG.Phys    =this.S_101_COG.Phys;
  canWrite(MyCANch,STD_GPS_SogCog);
}

on CanMessage <MyCANch> TEST_MSG_201 {

  FD_GPS.S_101_ROLL.Phys    =this.S_201_ROLL.Phys;
  FD_GPS.S_101_PITCH.Phys   =this.S_201_PITCH.Phys;
  FD_GPS.S_101_HEADING.Phys =this.S_201_HEAD.Phys;

  FD_GPS_TEST= (FD_GPS_TEST | 1);  

  if (FD_GPS_TEST>=7) {
    canWrite(MyCANFDch,FD_GPS);
    FD_GPS_TEST=0;
  }
}

on CanMessage <MyCANch> TEST_MSG_202 {

  FD_GPS.S_101_LAT.Phys  =this.S_202_LAT.Phys;
  FD_GPS.S_101_LON.Phys  =this.S_202_LON.Phys;
  FD_GPS.S_101_ALT.Phys  =this.S_202_ALT.Phys;

  FD_GPS_TEST= (FD_GPS_TEST | 2);  

  if (FD_GPS_TEST>=7) {
    canWrite(MyCANFDch,FD_GPS);
    FD_GPS_TEST=0;
  }
}

on CanMessage <MyCANch> TEST_MSG_203 {

  FD_GPS.S_101_COG.Phys  =this.S_203_COG.Phys;
  FD_GPS.S_101_SOG.Phys  =this.S_203_SOG.Phys;

  FD_GPS_TEST= (FD_GPS_TEST | 4);  

  if (FD_GPS_TEST>=7) {
    canWrite(MyCANFDch,FD_GPS);
    FD_GPS_TEST=0;
  }
}

8 Appendix C, File structure on storage area

The internal format of the storage area is following the FAT-32 format, but there are several restrictions in how we can use the memory area.

We do not have any support for DIRECTORIES, so all files are located in the ROOT of the memory area.

The DIN Rail SE410S-X10, uses the 8.3 filename convention.

Legal characters for the filenames include the following:
Upper case letters A–Z
Lower case letters a–z (Used as A–Z)
Numbers 0–9
Underscore “_”

Non allowed:
ASCII 0 – ASCII 32 (Control characters 0–31 and SPACE)
ASCII127 – ASCII255 (including DEL(127))
” * + / : ; < = > ? \ [ ] |
! @ (Is allowed in some file systems, but let us avoid them)
# $ % & ‘ ( ) – ^ ` { } ~

On other Kvaser interfaces, there might be some files already on the memory area (like on a Kvaser Memorator).

Please do not use any of these filenames:
*.LIF
LOG*.KMF
DATABASE.BIN

Also avoid these filenames, they are allowed on Kvasers units, but might cause errors when copied.
COM, COM1, COM2, COM3
LPT, LPT1,LPT2,LPT3
CON
DEVICE

Files names with predefined functions
AUTOEXEC.TXT (Used for startup of *.TXE files)

Author Image

Lars-Göran Fredriksson

Lars-Göran Fredriksson is a Field Application Engineer for Kvaser AB. His background is in geographic information system (GIS) and Remote Sensing and his current focus is on connecting the deep knowledge of Kvaser's developers with the practical questions of our end users. If you doubt his passion for CAN, just know that his first week in the office he created an interactive CAN Trivia game that sent the office scouring the halls for the correct answers. He is a passionate fisherman who would like to develop new environmentally friendly fishing methods. Biggest catch and release fish is for the moment a Bluefin Tuna at appr 325kg / 715lbs.