When key 'a' is pressed message should be transmitted
after every 10sec to CAN bus
variables
message msgA = {0x123, d8}; // Example CAN ID
on key 'a'
write("Key 'a' pressed. Starting 10-second cyclic transmission.");
setTimerCyclic(msgTimer, 10000); // Start cyclic timer (10 sec)
on timer msgTimer
// Fill example data (optional)
[Link](0) = 0xAA;
[Link](1) = 0x55;
output(msgA); // Send to CAN bus
write("Message sent on CAN ID 0x123");
Write a code in capl- send msg1 of periodicity 1s
10times stop msg1 and start msg2 11th time
variables
{
message msg1 = {0x100, d8}; // Example CAN ID for msg1
message msg2 = {0x200, d8}; // Example CAN ID for msg2
int send_count = 0;
on start
setTimer(sendTimer, 1000); // Start 1-second timer
on timer sendTimer
send_count += 1;
if (send_count <= 10)
// Fill msg1 with sample data (optional)
[Link](0) = send_count; // Just for demo
output(msg1);
write("Sent msg1, count: %d", send_count);
else
// Fill msg2 with sample data (optional)
[Link](0) = send_count; // Just for demo
output(msg2);
write("Sent msg2, count: %d", send_count);
// Continue periodic timer
setTimer(sendTimer, 1000);
Write a code in CAPL where ECU name is EMS, can id=
0x350, vehicle speed should be between 0-240m/s and
3rd and 5th byte corresponds to CRC and alive counter
and it should send data periodically 10ms with an inc in
vehicle speed. Above 240m/s it should print invalid
speed.
variables
message EMS_MSG = {0x350, d8}; // CAN ID 0x350, 8 data bytes
int vehicle_speed = 0;
int alive_counter = 0;
on start
setTimer(SendEMSMessage, 10); // Start periodic timer
on timer SendEMSMessage
// Check if speed exceeds the limit
if (vehicle_speed > 240)
write("Invalid speed: %d m/s", vehicle_speed);
vehicle_speed = 0; // Reset speed
}
// Assign vehicle speed to the first two bytes (assuming little-endian format)
EMS_MSG.byte(0) = vehicle_speed & 0xFF;
EMS_MSG.byte(1) = (vehicle_speed >> 8) & 0xFF;
// CRC and Alive Counter Handling
EMS_MSG.byte(2) = CalculateCRC(EMS_MSG); // Assuming a CRC calculation function
EMS_MSG.byte(4) = alive_counter & 0xFF;
// Send message on CAN bus EMS
output(EMS_MSG);
// Increment vehicle speed
vehicle_speed += 1;
// Increment and roll over alive counter (0-255)
alive_counter = (alive_counter + 1) % 256;
// Restart timer for next cycle
setTimer(SendEMSMessage, 10);
// Now monitor and read your own transmitted message 0x350on message 0x350
EMS_MSG_RX = this; // Store received message
write("Received message from CAN ID 0x351: [%02X %02X %02X %02X %02X %02X %02X %02X]",
EMS_MSG_RX.byte(0), EMS_MSG_RX.byte(1), EMS_MSG_RX.byte(2), EMS_MSG_RX.byte(3),
EMS_MSG_RX.byte(4), EMS_MSG_RX.byte(5), EMS_MSG_RX.byte(6), EMS_MSG_RX.byte(7));
}
Write a CAPL code to first pack the values in the CAN
msg and then send it to CAN bus and then extract and
read it
variables
dword voltage = 230; // Voltage (32-bit)
dword current = 12; // Current (32-bit)
message CANMessage; // CAN message object to send/receive
on start
// Step 1: Pack the Voltage and Current into the CAN message
// Packing Voltage (Bytes 0 to 3)
[Link](0) = (voltage & 0xFF); // Byte 0 (lowest byte)
[Link](1) = (voltage >> 8) & 0xFF; // Byte 1
[Link](2) = (voltage >> 16) & 0xFF; // Byte 2
[Link](3) = (voltage >> 24) & 0xFF; // Byte 3
// Packing Current (Bytes 4 to 7)
[Link](4) = (current & 0xFF); // Byte 4 (lowest byte)
[Link](5) = (current >> 8) & 0xFF; // Byte 5
[Link](6) = (current >> 16) & 0xFF; // Byte 6
[Link](7) = (current >> 24) & 0xFF; // Byte 7
// Step 2: Send the packed CAN message with ID 0x100
output(CANMessage, 0x100); // Sending message to CAN bus
// Step 3: Print the packed values to confirm before sending
write("Sending Voltage: %u V", voltage);
write("Sending Current: %u A", current);
// This event is triggered when CAN message 0x100 is received
on message 0x100
// Step 4: Extract the Voltage and Current from the received message
voltage = [Link](0) |
([Link](1) << 8) |
([Link](2) << 16) |
([Link](3) << 24);
current = [Link](4) |
([Link](5) << 8) |
([Link](6) << 16) |
([Link](7) << 24);
// Step 5: Print the extracted values from the received message
write("Received Voltage: %u V", voltage);
write("Received Current: %u A", current);
Write a CAPL script to extract and process a signal from
a CAN message.
on message 0xA00 {
int rpm = ([Link](1) << 8) | [Link](0);
write("Engine RPM: %d", rpm);
}
Write a CAPL script to detect bus-off and restart CAN
communication.
on busOff {
write("Bus Off detected! Restarting CAN...");
restartCAN();
Write a CAPL script to check if a specific bit is set in a
message byte.
on message 0x800 {
if ([Link](0) & 0x01) {
write("Bit 0 is set in byte 0");
Write a CAPL script to process only messages with IDs
0x500 and 0x600.
on message * {
if ([Link] == 0x500 || [Link] == 0x600) {
write("Filtered Message ID: 0x%X", [Link]);
Explanation:
if ([Link] == 0x500 || [Link] == 0x600) filters messages with specific IDs.
📚 Data Types in CAPL
Here are the most commonly used data types in CAPL:
Data Type Size Meaning / Usage
char 8 bits (1 byte) Small integer or ASCII character
byte 8 bits (1 byte) Unsigned 8-bit value (0-255)
word 16 bits (2 bytes) Unsigned 16-bit value (0-65535)
long 32 bits (4 bytes) Signed 32-bit value (-2B to +2B)
dword 32 bits (4 bytes) Unsigned 32-bit value (0 to ~4B)
int 16 bits (2 bytes) Signed 16-bit value (-32K to +32K)
float 32 bits (4 bytes) Decimal numbers (floating point)
double 64 bits (8 bytes) Higher precision decimal numbers
msTimer Special Timer used for delays, measurements
bool 8 bits (1 byte) Boolean true/false
string Variable length Text (array of characters)
✅ Common Format Specifiers:
Format Meaning Example
%c Character 'A'
%d Signed decimal integer -123
%u Unsigned decimal integer 255
%x Unsigned hexadecimal (lowercase) 0x1f4
%X Unsigned hexadecimal (uppercase) 0x1F4
%f Float value (decimal) 3.1415
%s String "Hello"