Scripts for CANtrace

A powerful CAN bus analyser software and diagnostic tool

CANtrace Python Scripts.

Here on this page is a collection of awesome Python scripts that automate CANtrace tasks and make our lives easier… or both!

You can download and use the scripts freely. Copy or download the python script from the accordion below and paste it into the CANtrace scripting tab. Enjoy!

This code defines three functions related to bus operations:

  1. onbusFunc(): This function is executed once when the system goes on the bus.
  2. offbusFunc(): This function is executed once before the system goes off the bus.
  3. recvFunc(canmsg): This function is executed for every message received and for transmit acknowledgments of sent messages.
# This function is run once after going on bus
def onbusFunc():
    return

# This function is run once before going off bus
def offbusFunc():
    return

# This function is run for every message received (and also tx-ack for sent messages)
def recvFunc(canmsg):
    return True


This function checks if the message identifier (canmsg.Id) is in a predefined blacklist of identifiers (blacklist = [11, 13, 55]). If the identifier is blacklisted, the function returns False, indicating that the message should be dropped and not displayed or logged. If the identifier is not blacklisted, the function returns True, allowing the message to be processed.

# Function handling incoming signals
def recvFunc(canmsg):
    # Vector of blacklisted Identifiers
    blacklist = [11, 13, 55];
    
    if canmsg.Id in blacklist:
        return False; # Drops message, will not be displayed or logged
    return True;


Processes incoming CAN messages from channel 1 with ID 385, applies a FIR filter to the message data, and sends the modified message to a virtual channel while allowing the original message to pass through unchanged. It converts and filters the data, then duplicates the original message’s information into the new message before sending it.

# Creates a new signal calculated from an existing signal
# The new signal can be used in Trace, Data and Graph view

# Script takes incoming message from desired channel
# Creates a new message, copies original message data to it
# Calculates FIR filtered data and adds it to the new message
# Sends new message to virtual channel and original message goes through as normal

meanValue = 0

# Function that handles all incoming messages
def recvFunc(canmsg):
    if (canmsg.Channel == 1 and canmsg.Id == 385):
        global meanValue    
        newmsg = CanMsg() # New message to be modified 
        
        # Change to 16 bit for data calculations
        currentValue = (canmsg.Data[1]<<8)|canmsg.Data[0] # Support negative values if currentValue >= 32768:
            currentValue = -65536 + currentValue

        # Calculates FIR filtered value
        meanValue = (5 * meanValue + currentValue)/6
    
        # Copy information from original message to new message
        newmsg.Id = canmsg.Id
        newmsg.Channel = canmsg.Channel
        newmsg.Dlc = canmsg.Dlc
        newmsg.TimeStamp = canmsg.TimeStamp
        newmsg.IsTxAck = canmsg.IsTxAck       
        newmsg.IsExtendedId = canmsg.IsExtendedId
        newmsg.IsRtr = canmsg.IsRtr
        newmsg.IsErrorFrame = canmsg.IsErrorFrame

        # Insert filtered data to new message
        newmsg.Data[1] = (meanValue >> 8) & 0xff
        newmsg.Data[0] = meanValue & 0xff

        ctapi.Send(2, newmsg) # Send new message to desired channel
        
    return True # Return True = original canmsg goes through also


This Python script logs CAN messages to a file in Peak format. It opens the log file when the bus is accessed, writes each received message to the file with detailed formatting, and closes the file when the bus is no longer accessed.

import time

# Log CAN messages to a file in Peak format

# This function is run once after going on bus
def onbusFunc():
    # Open the log file
    global logfile;
    global msgCnt;

    logFilename = "c:\logfiles\CANtrace-log-file.trc";

    msgCnt = 0;
    logfile = open( logFilename, "w");
    logfile.write( ';$FILEVERSION=1.1\n')
    logfile.write( ';$STARTTIME=\n')
    logfile.write( ';\n')
    logfile.write( ';   ' + logFilename + '\n')
    logfile.write( ';\n')
    logfile.write( ';   Start time: ' + time.strftime("%d.%m.%Y %H:%M:%S") + '\n')
    logfile.write( ';\n')
    logfile.write( ';   Message Number\n')
    logfile.write( ';   |         Time Offset (ms)\n')
    logfile.write( ';   |         |        Type\n')
    logfile.write( ';   |         |        |        ID (hex)\n')
    logfile.write( ';   |         |        |        |     Data Length Code\n')
    logfile.write( ';   |         |        |        |     |   Data Bytes (hex) ...  \n')
    logfile.write( ';   |         |        |        |     |   |                     \n')
    logfile.write( ';---+--   ----+----  --+--  ----+---  +  -+ -- -- -- -- -- -- --\n')

    return False

# This function is run once before going off bus
def offbusFunc():
    # Close the log file so we don't lose data
    global logfile;

    logfile.close();

    return

# This function is run for every message received (and also tx-ack for sent messages)
def recvFunc(canmsg):
    # Log - Log messages to your custom log file
    global logfile;
    global msgCnt;
    global TXRX

    logLine = '{:>6}'.format(str(msgCnt)) + ")"
    logLine += '{:>12}'.format(str(canmsg.TimeStamp*1000))
    if canmsg.IsTxAck:
        TXRX = "Tx"
    else:
        TXRX = "Rx"
    logLine += '{:>4}'.format(str(TXRX))
    logLine += '         {:04X}'.format(int(canmsg.Id))
    logLine += '{:>3}'.format(str(canmsg.Dlc)) + ' '
    for byteNum in range(0, canmsg.Dlc):
        logLine += ' {:02X}'.format(int(canmsg.Data[byteNum]))
    logfile.write(logLine + "\n");

    msgCnt = msgCnt + 1;

    return True


This Python script dynamically modifies the data of a message from the Send Tab. It toggles a specific bit in the message data for every other message received on channel 2 with ID 52, sends the modified message to a real channel (channel 1), and then restores the original message data.

# Dynamicaly changes data of message from Send Tab

# Message from Send tab is sent to virtual channel
# The Python code reads the message, changes it, and sends it on a real channel
# One bit in the message is toggled for every other message

togglebit = 0

# Function handling incoming signals
def recvFunc(canmsg):
    # Create a global variable
    global togglebit

    # Toggle bit for specific channel
    if (canmsg.Channel == 2 and canmsg.Id == 52):
        original = canmsg.Data[:]
        if togglebit == 0:
            togglebit = 1
            canmsg.Data[3] = 128 # Changes one bit in data
        else:
            togglebit = 0
        
        ctapi.Send(1, canmsg) # Sends toggled data to channel 1
        
        canmsg.Data = original # Returns original msg back to original state
    return True


This Python script defines a function that processes incoming signals by checking if the message identifier is in a predefined whitelist. If the identifier is in the whitelist, the function returns True, allowing the message to be displayed and logged. If not, it returns False, preventing the message from being displayed or logged.

# Function handling incoming signals
def recvFunc(canmsg):
    # Vector of whitelisted Identifiers
    whitelist = [11, 13, 55];
    
    if canmsg.Id in whitelist:
        return True # Message gets displayed and logged
    return False