CAN Tutorial

Hardware Configuration

Ethernet CAN Gateway

Configuration (Raw Ethernet mode)

Here the Ethernet CAN gateway can be configured by setting target MAC Address and the EtherType of the RAW frames. Non-valid entries will not be accepted and will be replaced by default values. If either the target MAC address or the EtherType has the default value set, the Ethernet CAN Gateway will be disabled.

../_images/MGConfig.png
  1. Choose Raw mode.

  2. Select the appropriate bus.

  3. Set the Target MAC address.

  4. Put EtherType in hexadecimal format in this example.

CAN Hardware

Adding J2534 PassThru

../_images/adding_j2534.gif

Warning

Byte Alignment in J2534 (PassThru):

As a 64-bit application, ANDi uses 64-bit drivers provided by other vendors to access to their hardwares.

It was found that existing drivers from other vendors are using a byte alignment that does not match the J2534 specification (J2534_1_2004 specification: section 9.2.2 Attaching to the Dll From an Application).

ANDi implemented its J2534 functionality using this non-standard-conform byte alignment by default to support existing drivers from other vendors. In case you find that your Third-Party Hardware Device, using J2534, is not working with ANDi (causing crashes), please ask the driver's vendor about its "Byte Alignment implementation".

From ANDi v1.25 and higher, it is possible to switch to the standard-conform variant through the "Byte Alignment" Property:

  • Aligned: This is the default, and compatible with vendors such as Peak System, Kvaser, Intrepid and Vector.

  • Packed: This is the standard behavior, no known vendors use this at the moment.

If you are unsure about what to choose, please contact your driver's vendor.

Configuration

To configure the CAN hardware, 3 parameters could be set:

  1. CAN Mode (CAN or CAN-FD).

  2. Bitrate: (100 000, 125 000, 250 000, 500 000, 1 000 000).

  3. Data Bitrate if the CAN-FD Mode is chosen (250 000, 500 000, 1 000 000, 2 000 000, 5 000 000, 8 000 000).

  4. Sample Point for CAN-FD Mode

../_images/CANHardwareConfig.png

Scripting

To send or receive CAN messages, it is necessary to configure the Hardware device first. It can be a CAN case device or a Technica Media Gateway. Once the device is configured and assigned to a communication channel, it is possible to send and receive CAN messages. It is also necessary to add the appropriate FA_CAN database.

CAN device configuration

CAN Case

  • to configure the hardware CAN case, it is important to setup the vector driver

  • if the vector driver is already installed and your CAN case is connected to the PC, you can check from the control panel under " vector Hardware" if the channel 1 and channel 2 of the CAN case are configured

Send CAN messages

def initialize_can_message(can_msg, can_id, can_length, can_data, data_base):
    can_msg.can_header.message_id = can_id
    can_msg.can_header.length = can_length
    can_msg.payload = can_data
    can_msg.data_base = data_base

ID = 0x04
LENGTH = 0x04
DATA = Array[Byte]((0x01, 0x02, 0x03, 0x04))

can_msg = message_builder.create_can_message(channel_01.name, channel_01.name)
print("Initialize CAN message...")
initialize_can_message(can_msg, ID, LENGTH, DATA, None)
print("Sending CAN message... ")
can_msg.send()

CAN messages capture

def tc_prepare_capture(msg, call_back_function):
    msg.on_message_received += call_back_function
    msg.start_capture()
    return

def on_msg_received(msg):
    print("CAN message received... ")
    print(msg)

can_msg = message_builder.create_can_message(channel_01.name, channel_01.name)
tc_prepare_capture(can_msg, on_msg_received)
print("Verify CAN message... ")
tc_wait_for_return(1000)

CAN message signals interpretations

def tc_prepare_capture(msg, call_back_function):
    msg.on_message_received += call_back_function
    msg.start_capture()
    return

def initialize_can_message(can_msg, can_id, can_length, can_data, data_base):
    can_msg.can_header.message_id = can_id
    can_msg.can_header.length = can_length
    can_msg.payload = can_data
    can_msg.data_base = data_base
    
def check_can_signals_interpretations(can_msg, signals_params, signals_interpretations):
    set_errors = set()
    dic_signals_interpretations = can_msg.get_all_signals_interpretations()
    print(dic_signals_interpretations)
    print("**signals_interpretations**")
    print(signals_interpretations)
    if dic_signals_interpretations != None :
        if len(signals_params) > 0 : #and len(dic_signals) > 0:
            counter = 0
            for index in signals_params:
                if (signals_interpretations[counter] != None and dic_signals_interpretations[index] != signals_interpretations[counter]):
                    set_errors.add("wrong signal received {0}, signal interpretation must be {1}".format(dic_signals_interpretations[index], signals_interpretations[counter]))
                counter += 1
    return set_errors

def on_msg_received(msg):
    print(msg)
    check_can_signals_interpretations(msg, SIGNALS_PARAMS, SIGNALS_INTERPRETAIONS)

ID = 0x88
LENGTH = 0x08
DATA = Array[Byte]((0x17, 0x49, 0x54, 0x8D, 0xFF, 0xFF, 0xFF, 0xFF))
SIGNALS_PARAMS = ["CRC_CTR_MONI_FSFY", "ALIV_CTR_MONI_FSFY", "CTR_MONI_FSFY", "INQY_ANSW_MONI_FSFY"]
SIGNALS_INTERPRETAIONS = [23, "Zählerstand 0..E","Antwort", 36180]
set_errors =  set()

can_msg = message_builder.create_can_message(channel_01.name, channel_01.name)
tc_prepare_capture(can_msg, on_msg_received)
print("Initialize CAN message...")
initialize_can_message(can_msg, ID, LENGTH, DATA, can_database)
print("Sending CAN message... ")
can_msg.send()
print("Verify CAN message... ")
tc_wait_for_return(1000)

CAN message signals store captured messages

def tc_prepare_capture(msg, call_back_function):
    msg.on_message_received += call_back_function
    msg.start_capture()
    return

def initialize_can_message(can_msg, can_id, can_length, can_data, data_base):
    can_msg.can_header.message_id = can_id
    can_msg.can_header.length = can_length
    can_msg.payload = can_data
    can_msg.data_base = data_base

def on_msg_received(msg):
    msg.store()
    tc_return_continue()

ID = 0x52A
LENGTH = 0x04
DATA = Array[Byte]((0x01, 0x02, 0x03, 0x04))
CAN_MSG_NUMBERS = 5
save_path = "C:\\Users\\Technica\\Desktop\\StoredCAN.pcapng"

can_msg = message_builder.create_can_message(channel_01.name, channel_01.name)
tc_prepare_capture(can_msg, on_msg_received)
print("Initialize CAN message...")
initialize_can_message(can_msg, ID, LENGTH, DATA, can_database)
can_msg.auto_save = False
can_msg.open_writer(save_path)
print("Sending CAN message... ")
for i in range(CAN_MSG_NUMBERS):
    can_msg.send()
    tc_wait_for_return(1000)

can_msg.close_writer()

Database

see details in CAN Database.