CAN Message Timestamp Update
This example demonstrates how to update and display timestamps for received CAN messages in real-time.
Overview
The script monitors all CAN messages and updates a timestamp each time a message is received on CAN channel 1. This is useful for debugging and monitoring message traffic.
Complete Example
/* File: TimestampUpdate.capl */
/* Variables */
variables {
// Timestamp tracking
long lastTimestamp;
long currentTimestamp;
long timeDifference;
// Message counter
int messageCount = 0;
// Timing control
msTimer updateTimer;
const int UPDATE_INTERVAL = 100; // Update every 100ms
}
/* Initialization */
on start {
write("Starting CAN Timestamp Monitor");
lastTimestamp = 0;
messageCount = 0;
// Start update timer
setTimer(updateTimer, UPDATE_INTERVAL);
}
/* Main event handler for all CAN1 messages */
on message CAN1::* {
messageCount++;
// Get current system time in microseconds
currentTimestamp = timeNowUs();
// Calculate time difference from last message
if (lastTimestamp > 0) {
timeDifference = currentTimestamp - lastTimestamp;
} else {
timeDifference = 0;
}
// Update last timestamp
lastTimestamp = currentTimestamp;
// Display message information
write("=== Message #%d ===", messageCount);
write("ID: 0x%03X (%d)", this.ID, this.ID);
write("DLC: %d bytes", this.DLC);
write("Timestamp: %d μs", currentTimestamp);
write("Time since last: %d μs", timeDifference);
// Display data bytes
write("Data: ");
int i;
for (i = 0; i < this.DLC; i++) {
write(" Byte %d: 0x%02X (%d)", i, this.byte(i), this.byte(i));
}
write("==================");
}
/* Periodic update */
on timer updateTimer {
float frequency;
float messageRate;
if (timeDifference > 0) {
frequency = 1000000.0 / timeDifference; // Convert to Hz
write("Current frequency: %.2f Hz", frequency);
}
// Calculate messages per second (based on last 1 second)
messageRate = messageCount / (UPDATE_INTERVAL / 1000.0);
write("Average rate: %.2f msg/s", messageRate);
// Reset counter for next interval
messageCount = 0;
// Restart timer
setTimer(updateTimer, UPDATE_INTERVAL);
}
/* Cleanup */
on stop {
write("Stopping CAN Timestamp Monitor");
write("Final message count: %d", messageCount);
}
Key Functions Used
timeNowUs()
Returns the current system time in microseconds. This provides high-resolution timing for precise measurements.
long timestamp = timeNowUs();
setTimer(timer, interval)
Sets a timer to trigger after a specified interval in milliseconds.
setTimer(updateTimer, 100); // Trigger after 100ms
on timer timerName
Event handler that executes when the specified timer expires.
on timer updateTimer {
// Timer logic here
}
Output Example
When you run this script, you'll see output similar to:
=== Message #1 ===
ID: 0x100 (256)
DLC: 8 bytes
Timestamp: 15478923 μs
Time since last: 0 μs
Data:
Byte 0: 0x01 (1)
Byte 1: 0x02 (2)
Byte 2: 0x03 (3)
Byte 3: 0x04 (4)
Byte 4: 0x05 (5)
Byte 5: 0x06 (6)
Byte 6: 0x07 (7)
Byte 7: 0x08 (8)
==================
Use Cases
This example is useful for:
- Message Frequency Monitoring: Track how often messages are transmitted
- Timing Analysis: Measure time intervals between messages
- Debugging: Verify message reception and timing
- Performance Testing: Monitor message rates and throughput
- Bus Load Calculation: Determine actual bus utilization
Variations
Log to File Instead of Write Window
on message CAN1::* {
char logFile[100];
sysLogWrite(logFile, LOG_MODE_FILE, "ID: 0x%03X", this.ID);
}
Filter Specific Messages
on message CAN1::EngineData {
// Only process EngineData messages
write("Engine speed: %d RPM", this.EngineSpeed);
}
Calculate Running Average
variables {
float frequencyHistory[10];
int historyIndex = 0;
}
on timer updateTimer {
frequencyHistory[historyIndex] = frequency;
historyIndex = (historyIndex + 1) % 10;
// Calculate average
float sum = 0;
int i;
for (i = 0; i < 10; i++) {
sum += frequencyHistory[i];
}
float average = sum / 10.0;
write("Average frequency: %.2f Hz", average);
}
Best Practices
- Use appropriate timers: Match timer interval to your update needs
- Handle edge cases: Check for first message (no previous timestamp)
- Performance: Don't do heavy processing in message handlers
- Formatting: Use consistent formatting in output
- Logging: Consider file logging for long-term monitoring
Next Steps
- Implement message filtering for specific IDs
- Add statistical analysis (min, max, average times)
- Create graphical display of timing data
- Log data to file for post-processing