How to work with CAN in VIGO6

A short introduction to CAN in VIGO6:

This tutorial assumes a basic knowledge of VIGO6. It aims to explain how to build a component that facilitates sending and receiving CAN-bus data. A demo_project is available in VIGO6: PD_22943-01 - CAN_bus_demo, and the different components are available in the catalogue: PD_22861-01 - CAN-bus-demo. Further information is found in the documentation for the CAN hardware interface, PD_15325-09.

PD610 CAN features:
  • 16 individual CAN telegrams (different ID’s). Either transmit or receive
  • 11 bit CAN ID; (CAN 2.0A)
  • CAN 2.0B is theoretically possible, but not planned for implementation.

The CAN-module used to communicate with in this demo/example:

PEAK PCAN-MIO industrial

2 telegrams are configured in the CAN module. The CAN telegrams are shown here:

  • One telegram with 2 voltages (resolution 10 mV) and 2 digital input values. COB-ID is 101(HEX) and byte order Intel(little-endian)
  • One telegram with a digital output. COB-ID is 181(hex) and byte order Intel(little-endian)

The CAN bus hardware interface:

Make your own CAN-telegram interface (converter) as a descendant of the basic CAN-bus hardware interface

You need to make one interface for each CAN-telegram. In the following step-by-step-description we will work with the CAN-telegram Level_in.

CAN_bus control component:

Hardware Interfaces are subcomponents and hence must have a component in which to reside.

Create a new component as a descendant of the process-component and add your can-bus-hardware interface(s) to it.


Raw CAN-telegram in VIGO6:

Create a record-structure to match the CAN-telegram.

Digital_in_0 and Digital_in_1 – select datatype uint8 (1 byte).
Voltage_0 and Voltage_1 – select datatype uint16 (2 bytes)

Where to place the data:

Add the CAN-record structure as a volatile variable in the volatile variables section of your CAN bus hardware-interface.

NB! It is important that the CAN-record structure is the FIRST volatile data you add. This way the data has offset 0 seen from the COPP-editor, and we need that for our coming mapping. "Mapping" is a CANopen term, which can loosely be translated to "location of data".

Mapping of the CAN telegram <-> data in COPP:

Now set the mapping between the CAN telegram and the raw CAN-data defined in VIGO6. This will enable the hardware interface to transfer data from the CAN-record to the COPP-record. This is done whenever the hardware-interface receives new data (whereby the method “notification” is called).

  1. Set CAN ID
    The CAN_ID is 11 bits, but often represented as 4 bit and 7 bit (see illustration)

In our case, we have a COB_ID, which is a representation of all 11 bits.

The COB_ID is 101 in HEX – corresponding to (0)00100000001 in binary (only 11 bits) (tip: the standard calculator in windows can be switched to “programmer” and then you can see the conversions)

Now divide the 11 bits into 4 bits function code (0010) and 7 bits NodeID (0000001)
We need to enter a decimal value into the editor, so we must convert the two binary values to decimal

i.e. Function code = 2 and NodeID = 1

  1. Select CAN device role

The CAN device role indicates whether the telegram is data that the CAN device expects to receive or whether it is data it can send. In the case of our telegram Level_in, this is data the CAN device wants to receive (hence the “IN”), so we set can device role to “receiving”.


  1. Set mapping

Now we need, bit by bit, to indicate the transfer of bits from the CAN-telegram into proper COPP-variables. This happens in two steps. 

First we transfer the bit-stream into a record structure of uint-variables (CAN_level_in_demo_rec) 

Next we convert the data from the uint record into a record structure of proper COPP variables (COPP_level_in_demo_rec)


Let us revisit the CAN telegram definition:

We see that Byte order is Intel = little endian, so the least significant byte is sent first.

Hence, the first data we receive is Byte 0, then we receive Byte 1 etc.


So the operation we need to perform is this:

In the CAN-hardware-interface we need to indicate which bits from the CAN-telegram that must move into which parts of the data structure of the CAN_level_in_demo_rec.


We have a total of 4 elements (Voltage_0, Voltage_1, Digital_in_0 and Digital_in_1).


Each element need to be defined inside the CAN-hardware interface, through the instance constant “CAN_telegram_mapping_table”

Each element contain the following structure:

Reserved is not used. CAN_variable_endian can be “little” or “big”. In our case it is little.

“CAN_packet” represents the CAN-telegram structure and COPP_variable represents the COPP data structure; in our case “CAN_level_in_demo_rec.

The size indicates number of bits to be transferred (and NOT the size of the data structure element), and the Offsets must be in bits.

The data to fill in are therefore:



































Note that for the first 3 elements, offset and size are identical for the CAN-telegram and the CAN_level_in_demo_rec, but for element 4 (Digital_in_1) the offset in CAN is 33, whereas it is 40 in the CAN_level_in_demo_rec

Now we have data in CAN_level_in_demo_rec, but the data are represented as Quints and in fact they are floats (Voltage_0 and Voltage_1) and Booleans (Digital_in_0 and Digital_in_1), hence we map from CAN_level_in_demo_rec to a structure of floats and booleans that we call COPP_level_in_demo_rec.

CAN-telegram data in COPP format:

Make a record, representing the data in COPP-formats

The digital inputs are of type Qbool. The voltages are Float32 with quantity Voltage. Remember to set the Value range of the two voltages.

Add the COPP_Level_in_demo_rec as a volatile variable to your CAN bus hardware interface.

We also need to remember that Voltage_0 and Voltage_1 is in resolution 10 mV from the CAN-bus

To implement the conversion of data, we override the built-in Notification_method, which is automatically called every time there are new data on the CAN-bus.

Expose data in COPP:

The final thing we must do is make the data available to other components (and visualization) in COPP.

This is done by declaring a get/set-method pointing to our data structure : COPP_level_in_demo_rec.

Visualize the data:

Make a visualization of the data.

First: make a record visualization of COPP_level_in_demo_rec

This visualization can then be used in a component - or assembly visualization.

Set CAN baud:

Finally; remember to set the baudrate (default is 500 kbit), in the project or project assembly