Example 1: A large customer had an intermittent problem on a drivetrain bus. The suspected cause was a faulty multipacket broadcast data transfer (BAM), with packets being received out of sequence. An engineer spent a few days in a truck along with the driver, trying to catch a trace of the problem, before trying out a Kvaser Memorator Pro and TRX.
Said the customer: “I wrote a quick data logging routine that checks for mis-matched BAM packets on the CAN traffic, and when seen, saves data to a buffer.”
With a little help from Kvaser Support, the customer confirmed: “The logger worked exactly as needed … it was much easier than the options we had in the past.”
Example 2: A small company used TRX to develop a t program to replace the vehicle under test, a recreational vehicle in this case, that they had rented for testing purposes but were about to lose.
Specifically, their t program needed to highlight the on/off state of a light when testing a command sent from an iPad. “Can we create a device to monitor the CAN bus and send a specific message when we receive a command?”, they asked. Kvaser helped provide the code for this project, which can be shared and is available here.
Download Example t script >>
/*
** This program will test the dimmer response per the RV-C spec..
** By Bryan Hennessy
** -----------------------------------------------------------------------------------------
*/
variables {
Timer msgTimer01; //Define the variable that will be used in the timer. See t-Programming manual 2.10.2.4 for a full explanation on timers.
Timer msgTimer02; //Do the same for the rest of the timers
Timer msgTimer03;
Timer msgTimer11;
const int can_channel = 0;
const int can_bitrate = 250000;
const int Toggle01 = 0x1FEDB9F; //This is the toggle message with an SA of 9F.
byte status01_byte[8] = {0x01, 0xFF, 0x00, 0xFC, 0xFF, 0x12, 0x00, 0xFE}; //This is the data to broadcast and respond to a toggle command with.
byte status02_byte[8] = {0x02, 0xFF, 0x00, 0xFC, 0xFF, 0x12, 0x00, 0xFE}; //This is the data to broadcast and respond to a toggle command with.
byte status03_byte[8] = {0x03, 0xFF, 0x00, 0xFC, 0xFF, 0x12, 0x00, 0xFE}; //This is the data to broadcast and respond to a toggle command with.
byte status11_byte[8] = {0x11, 0xFF, 0x00, 0xFC, 0xFF, 0x12, 0x00, 0xFE}; //This is the data to broadcast and respond to a toggle command with.
int value = 0;
byte instance;
}
on start {
canSetBitrate(can_bitrate);
canBusOn();
msgTimer01.timeout = 2000; //Here we set the timer to count down 2000 msec, or two seconds, before it expires.
timerStart(msgTimer01, FOREVER); //Next we start the timer and set it to FOREVER so it reloads and starts again. Without the FOREVER it would only run once.
msgTimer02.timeout = 2000; //Here we set the timer to count down 2000 msec, or two seconds, before it expires.
timerStart(msgTimer02, FOREVER); //Next we start the timer and set it to FOREVER so it reloads and starts again. Without the FOREVER it would only run once.
msgTimer03.timeout = 2000; //Here we set the timer to count down 2000 msec, or two seconds, before it expires.
timerStart(msgTimer03, FOREVER); //Next we start the timer and set it to FOREVER so it reloads and starts again. Without the FOREVER it would only run once.
msgTimer11.timeout = 2000; //Here we set the timer to count down 2000 msec, or two seconds, before it expires.
timerStart(msgTimer11, FOREVER); //Next we start the timer and set it to FOREVER so it reloads and starts again. Without the FOREVER it would only run once.
}
/*
** Timer routine, sent with a fixed CAN ID = 0x19FEDA01 that gives Pri=6, PGN=1FEDA, SA =01
** You can change this message ID to anything you want as it's fixed in the msg.id statement below.
*/
on Timer msgTimer01 {
// printf("%02x %02x %02x %02x %02x %02x %02x %02x", status01_byte[0], status01_byte[1], status01_byte[2], status01_byte[3], status01_byte[4], status01_byte[5], status01_byte[6], status01_byte[7]);
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status01_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
}
on Timer msgTimer02 {
// printf("%02x %02x %02x %02x %02x %02x %02x %02x", status02_byte[0], status02_byte[1], status02_byte[2], status02_byte[3], status02_byte[4], status02_byte[5], status02_byte[6], status02_byte[7]);
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status02_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
}
on Timer msgTimer03 {
// printf("%02x %02x %02x %02x %02x %02x %02x %02x", status03_byte[0], status03_byte[1], status03_byte[2], status03_byte[3], status03_byte[4], status03_byte[5], status03_byte[6], status03_byte[7]);
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status03_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
}
on Timer msgTimer11 {
// printf("%02x %02x %02x %02x %02x %02x %02x %02x", status11_byte[0], status11_byte[1], status11_byte[2], status11_byte[3], status11_byte[4], status11_byte[5], status11_byte[6], status11_byte[7]);
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status11_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
}
on CanMessage<0> (Toggle01)x {
// If message received Toggle the light and send status
// if..... how do you ack on the data you receive? Check Data byte 0 and toggle that status_byte on and off
// The RV-C DBC file defines this byte as RVC_DIM_STATUS_INST
CanMessage_RVC_DIM_CMD_2 Command_Message; //The DBC file defines RVC_DIM_CMD_2 and we're going to use some of the signals in that message.
instance = Command_Message.RVC_DIM_CMD_INST.Raw; //This should put the first byte of RVC_DIm_CMD_2 in the byte "instance".
printf("We got a Toggle command for Instance %02x", instance); //This should print a message with the instance received in the command byte of Toggle01.
if (instance == 0x01) {
if (status01_byte[6] == 0x00) {
status01_byte[6] = 0x04;
status01_byte[1] = 0xC8;
} else {
status01_byte[6] = 0x00;
status01_byte[1] = 0x00;
}
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status01_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
return;
}
//only on CanMessage<0> (Toggle01)x { is open at this point
else {
if (instance == 0x02) {
if (status02_byte[6] == 0x00) {
status02_byte[6] = 0x04;
status02_byte[1] = 0xC8;
} else {
status02_byte[6] = 0x00;
status02_byte[1] = 0x00;
}
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status02_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
return;
}
else {
if (instance == 0x03) {
if (status03_byte[6] == 0x00) {
status03_byte[6] = 0x04;
status03_byte[1] = 0xC8;
} else {
status03_byte[6] = 0x00;
status03_byte[1] = 0x00;
}
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status03_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
return;
}
else {
if (instance == 0x11) {
if (status11_byte[6] == 0x00) {
status11_byte[6] = 0x04;
status11_byte[1] = 0xC8;
} else {
status11_byte[6] = 0x00;
status11_byte[1] = 0x00;
}
CanMessage msg;
msg.flags = canMSG_EXT;
msg.id = 0x19FEDA01; //gives Priority=6, PGN=1FEDA, SA =01
msg.dlc = 8;
for(int value = 0; value < 8; value++) {
msg.data[value] = status11_byte[value]; //This loop transfers the data from status_byte[x] to the message to be put on the bus.
}
canWrite(msg);
return;
}
}
}
}
}
on stop {
canBusOff();
}