CANopen Examples¶
Receive and send PDOs from a QML application¶
Using the LinX UX designer we can design and test sending CANopen signals on the virtual CAN bus withing the VM. Following example shows how to create a QML application and update it using LinX Manager Fieldbus Access to send and receive CANopen data on the CAN bus.
Prerequisites¶
Data Engine installed on target device.
Fieldbus Access 1.3.0 or greater installed on target device.
Interface
can0is up.can-utilsinstalled.
Data Engine and Fieldbus Access is pre-installed on UX Designer VM 4.0. Newer versions can be downloaded from the support site.
Create a QML project¶
Create a new project to use through the example.
Open Qt Creator.
File>New file or Project....Select
CrossControl Projectand pickQt Quick 2 Application.Follow the on-screen instructions to finalize the project creation:
Display resolution: 800x480
Kit: Desktop
Create a new CANopen bus¶
Open LinX Manager Fieldbus Access from the mode selector (left side).
Select the created project from the project selector drop-down menu.
Create a new CAN bus by pressing the add button
 and select
“Add new CANopen slave bus”.An empty CANopen bus is created with default settings.
Add transmit (TX) signal¶
Select “Transmitted Signals” tab from the middle panel.
Right mouse click and select “Add new signal”.
New signal created.
Double click the newSignal name and change it to “transmitSignal”.
| DE Signal | DE Datatype | Gain | Offset | OD Index | OD Subindex | 
|---|---|---|---|---|---|
| transmitSignal | INT | 1 | 0 | 2270 | 2 | 
Add receive (RX) signal¶
Select “Received Signals” tab from the middle panel.
Right mouse click and select “Add new signal”.
New signal created.
Double click the newSignal name and change it to “receiveSignal”.
| DE Signal | DE Datatype | Gain | Offset | OD Index | OD Subindex | 
|---|---|---|---|---|---|
| receiveSignal | INT | 1 | 0 | 2170 | 2 | 
Create TX PDO¶
Select “TPDO Mapping” tab from the middle panel.
Right mouse click and select “Add new PDO”.
New transmit PDO created.
Double click Transmission Type and set to
Asynchronous Manufacture Specific
| PDO Name | COB-ID | Tranmission Type | SYNCs | Inhibit T | Event T | Tot b. | 
|---|---|---|---|---|---|---|
| TPDO_1 | $NODEID+0x180 | Asynchronous Manufacture Specific (Type 254) | 0 | 
Create RX PDO¶
Select “RPDO Mapping” tab from the middle panel.
Right mouse click and select “Add new PDO”.
New receive PDO created.
Double click Transmission Type and set to
Asynchronous Manufacture Specific
| PDO Name | COB-ID | Tranmission Type | SYNCs | Inhibit T | Event T | Tot b. | 
|---|---|---|---|---|---|---|
| RPDO_1 | $NODEID+0x200 | Asynchronous Manufacture Specific (Type 254) | 0 | 
Map signals to PDO¶
Select “TPDO Mapping” tab from the middle panel.
Add the created signal to the PDO. On the TPDO_1, right mouse click and “Add signal”.
Do the same on “RPDO Mapping” tab.
| PDO Name | COB-ID | Tranmission Type | SYNCs | Inhibit T | Event T | Tot b. | 
|---|---|---|---|---|---|---|
| TPDO_1 | $NODEID+0x180 | Asynchronous Manufacture Specific (Type 254) | 32 | |||
| transmitSignal | 2270 | 2 | INT | 32 | 
Update the project¶
With the two PDOs created, the last step to perform with the plugin is to export the configuration and update the active project.
From the projector selector, press “Save” for the changes to take effect.
Verify that the project was updated by opening the General Messages tab (
Alt+6):LinX Manager Data Engine: Project updated successfully.
Selected project is now updated with new code and files. See How-tos for a complete list of generated files.
Snippet from dataengine.h:
class DataEngine : public DataEngineBase
{
    Q_OBJECT
    // Generated Signal MetaProperties
    Q_PROPERTY (ShortConsumerSignal* fieldbusAccess_CANopenError_CAN0 READ fieldbusAccess_CANopenError_CAN0 CONSTANT)
    Q_PROPERTY (ShortConsumerSignal* fieldbusAccess_CANopenStatus_CAN0 READ fieldbusAccess_CANopenStatus_CAN0 CONSTANT)
    Q_PROPERTY (IntProducerSignal* transmitSignal READ transmitSignal CONSTANT)
    Q_PROPERTY (IntConsumerSignal* receiveSignal READ receiveSignal CONSTANT)
Display PDO in QML¶
Values from the CAN-bus can now be visualized directly in the UI using the context property dataEngine. The
documentation for LinX Manager Data Engine contains further instructions how to use the context property (both from
QML and Widget projects).
Open
main.qmlwith the editorLocate
// add your GUI code below this lineAdd the following to display
receiveSignalin a Text component:Text { id: rxSignal_Label anchors.centerIn: parent font.pointSize: 20 color: "white" text: "RX Signal: " } Text { id: rxSignal anchors.left: rxSignal_Label.right anchors.top: rxSignal_Label.top color: dataEngine.receiveSignal.status ? "red" : "white" text: dataEngine.receiveSignal.value }
Send PDO value from QML¶
The snippet below will create two buttons in QML. When the first is clicked, it will update the TPDO transmitSignal  and set the value to -50. When the second button is clicked, it will update the same TPDO again and set the
value to 100. The value will be visible on the CAN bus when Fieldbus Access is running (future step).
Add this snippet beneath the code added in the previous section:
Rectangle { id: lowTXSignal width: 220; height: 60 anchors.top: rxSignal.bottom anchors.left: rxSignal_Label.left color: btnMouseArea1.pressed ? Qt.darker("grey", 1.5) : "grey" Text { anchors.centerIn: parent text: "Set value low" } MouseArea { id: btnMouseArea1 anchors.fill: parent onClicked: dataEngine.transmitSignal.value = -50 } } Rectangle { id: highTXSignal width: 220; height: 60 anchors.top: lowTXSignal.bottom anchors.left: rxSignal_Label.left color: btnMouseArea2.pressed ? Qt.darker("grey", 1.5) : "grey" Text { anchors.centerIn: parent text: "Set value high" } MouseArea { id: btnMouseArea2 anchors.fill: parent onClicked: dataEngine.transmitSignal.value = 100 } }
Start Fieldbus Access with generated configuration¶
The application is now prepared to send and receive value from/to the CAN bus. What’s left is to run Data Engine and Fieldbus Access to let it handle the CAN-communication.
Start Data Engine using the desktop shortcut.
Locate the generated configuration file for Fieldbus Access in the project directory.
[project directory]/LinXManager_FieldbusAccess/LinXManager_FA_configfile.json.Open a terminal and use the command
candump can0to view the traffic which is sent by Fieldbus Access to the CAN bus.Drag and drop the configuration on the Fieldbus Access shortcut found on the desktop.
Fieldbus Access start to execute based on the information found in the configuration.
Open a new terminal and use the command
cansend can0 000#0100to change Fieldbus Access state frompre-operationaltooperational.
Fieldbus Access will start and send initialization messages to the CAN bus.
ccs@LinX-VM:~$ candump can0
  can0  701   [1]  00
  can0  081   [8]  00 00 00 00 00 00 00 00
  can0  000   [2]  01 00
  can0  280   [8]  00 00 00 00 00 00 00 00
  can0  380   [8]  00 00 00 00 00 00 00 00
  can0  480   [8]  00 00 00 00 00 00 00 00
  can0  1A0   [8]  00 00 00 00 00 00 00 00
  can0  2A0   [8]  00 00 00 00 00 00 00 00
  can0  3A0   [4]  00 00 00 00
  can0  4A0   [8]  00 00 00 00 00 00 00 00
  can0  1B0   [8]  00 00 00 00 00 00 00 00
  can0  2B0   [8]  00 00 00 00 00 00 00 00
  can0  3B0   [8]  00 00 00 00 00 00 00 00
  can0  4B0   [8]  00 00 00 00 00 00 00 00
  can0  1C0   [4]  00 00 00 00
  can0  2C0   [8]  00 00 00 00 00 00 00 00
  can0  3C0   [8]  00 00 00 00 00 00 00 00
  can0  4C0   [8]  00 00 00 00 00 00 00 00
Send random PDO data and view in QML¶
With Data Engine and Fieldbus Access running from the previous step, it is now possible to read data from the CAN bus and display the result in the application created earlier.
Compile and start the application from Qt Creator.
Text field for
receiveSignalare displayed with the value assigned to zero.Open a terminal and use
cangento generate random data for PDO1.# Send 4 random bytes every second to PDO1 0x201 (OD Index 0x2170) ccs@LinX-VM:~$ cangen can0 -I 201 -L 4 -g 1000 -v can0 201#52.1E.11.6D can0 201#E1.2D.02.56 can0 201#F7.4A.03.4F can0 201#2B.E4.5C.29
Values for
receiveSignalis updated based on the values sent on the CAN bus. Color of the text is updated from red to white when the status value changes.
Send PDO value from QML (continued)¶
Pressing any of the two buttons will update transmitSignal (TPDO 1) and later
sent to the CAN bus by Fieldbus Access. The physical value from the application
is scaled with the configured gain and offset before it is visible on the CAN
bus.
| Physical | Gain | Offset | Raw (hex) | 
|---|---|---|---|
| -50 | 1 | 0 | 0xCEFFFFFF | 
| 100 | 1 | 0 | 0x64000000 | 
Use candump can0 to view the CAN frames sent by Fieldbus Access:
ccs@LinX-VM:~$ candump can0
  can0  181   [4]  CE FF FF FF              # Transmit value -50
  can0  2A0   [8]  00 00 00 00 CE FF FF FF 
  can0  181   [4]  64 00 00 00              # Transmit value 100
  can0  2A0   [8]  00 00 00 00 64 00 00 00
Display CANopen errors in a list view¶
The tool injects the project with a model which stores CANopen stack errors.
Information stored in the model can be displayed in QML, for example with a
ListView or TableView. The model is accessed via the context property
canopenStatusModel.
More information of how errors are generated and about CANopen error model can be found on the Error Handling page.
Example of a ListView in QML which displays four roles from the error model:
ListView {
    width: parent.width
    height: parent.height
    model: canopenStatusModel
    delegate: Row {
        width: parent.width
        spacing: 25
        Text {
            text: bus
        }
        Text {
            text: type
        }
        Text {
            text: message
        }
        Text {
            text: received
        }
    }
Show stack status in QML¶
The system signal fieldbusAccess_CANopenStatus_CAN# receives stack state
specific information from the Network Management (NMT).
| State | Code (hex) | 
|---|---|
| Initialisation | 0x00 | 
| Pre-Operational | 0x04 | 
| Operational | 0x05 | 
| Stopped | 0x7F | 
Open
main.qmlwith the editorAdd the following to display received status in a Text component:
Text { anchors.right: parent.right anchors.bottom: parent.bottom color: "#C00" font.pixelSize: 32; text: (dataEngine.fieldbusAccess_CANopenStatus_CAN0.value === FieldbusAccessCANopenStatusModel.NodeStateInitialisation) ? "Initialisation" : (dataEngine.fieldbusAccess_CANopenStatus_CAN0.value === FieldbusAccessCANopenStatusModel.NodeStateStopped) ? "Stopped" : (dataEngine.fieldbusAccess_CANopenStatus_CAN0.value === FieldbusAccessCANopenStatusModel.NodeStateOperational) ? "Operational" : (dataEngine.fieldbusAccess_CANopenStatus_CAN0.value === FieldbusAccessCANopenStatusModel.NodeStatePreOperational) ? "Pre Operational" : "N/A"; }
The state will change based on the reception of current CANopen stack status
from the Fieldbus Access runtime. This is done by comparing the
fieldbusAccess_CANopenStatus_<CAN0> signal value  with
FieldbusAccessCANopenStatusModel.<state>. CAN0 automatically added if “0” is the interface number selected in the bus settings.
Another suitable control that can be used is the StatusIndicator QML type.
Import QtQuick.Extras 1.4 to have access to this type. The indicator will be
shown in green when the status is in state Operational and unlit otherwise.
import QtQuick.Extras 1.4
StatusIndicator {
    anchors.centerIn: parent
    color: "green"
    active: dataEngine.fieldbusAccess_CANopenStatus_CAN0.value === FieldbusAccessCANopenStatusModel.NodeStateOperational
}
Test status property with CAN data¶
The status will quickly go from
InitialisationtoPre-Operational.Send CANopen master
operationalsignal.cansend can0 000#0100Status will change to
Operational.