CFD Language

General Description

Canny Function Diagram (CFD) is the programming language used to program CANNY controllers within the CannyLab IDE. During the development of the language, the goal was to create a tool which best suits the capabilities of the controller, while at the same time maintaining the industry standard. Function Block Diagram (FBD) Language was used as the starting point for the development of CFD. It’s fair to say that FBD is a contender for the most well-balanced among the five languages approved by the International Electrotechnical Commission for the purposes of creating user programs for PLC within the IEC 61131-3 standard.

As a graphical programming language, CFD has a high visual clarity comparable to wiring diagrams, but is at a higher level of abstraction. This lets you focus more on the overall algorithm of your program, rather than largely irrelevant implementation details.

Function Diagram

A program in the CFD language is called a function diagram. It’s a diagram that contains the function blocks, the connection lines (networks) linking those function blocks to each other, and miscellaneous supporting elements.

The algorithm of executing a program in the CFD language can be best described as a successive (usually from left to right) calculation of the output value of each function block, with the result transferring to the next connected function block for further calculations. We will refer to such an algorithm as a thread of execution.

CFD Program Execution Process.

Presenting the program this way makes it easy to trace the thread of execution, just by looking at the picture and following connection lines from block to block.

In CFD the relative position of blocks in an acyclic diagram – which means a diagram without a feedback loop – does not affect their execution order. Function block execution order of an acyclic diagram is described by the following rule: each function block is executed when all of its inputs are calculated.

A different rule applies to a cyclic diagram, which means a diagram with a feedback loop. The rule for a cyclic diagram is as follows: function blocks involved in the feedback loop are executed in such order, that the rightmost function block is always the last one to be executed. The relative vertical position does not impact the execution order within a feedback loop.

Note: The rule for the cyclic diagram only applies within the context of a feedback loop. Outside of feedback loops the relative position won’t impact the execution order, but it’s still good practice to arrange your diagrams in a consistent fashion.

Correctly structured feedback loop.

This feedback loop is structured correctly because it is clear which block needs to be executed last and the execution order is well defined. In an improperly structured feedback loop both function blocks have the same X coordinate, which leads to undefined execution order. In CannyLab v2 issues related to improperly structured feedback loops were fixed. However, improperly made loops will result in a warning being displayed.

Incorrectly structured feedback loop.

The above arrangement will result in a warning being displayed.

Function Block

The function block is a graphical element of a function diagram that indicates a function, an algorithm or a mathematical expression. The function block calculates its output data using the input data received from the outside. On the function block, the inputs are always positioned on the left and outputs on the right.

Function block.

CFD has many built-in function blocks. This includes simple blocks that perform basic logical operations on their input data – such as AND, OR, NOT – alongside more complex function: triggers, generators, switches.

Function blocks may have several inputs and several outputs. They can use both their own memory and access the controller’s system resources for calculations. For example, a function block can read data from a timer and use it for calculating its output values.

Function blocks interacting with each other

In the CannyLab environment, there are several valid sources of input data for a function block:

  • other function blocks whose output output is connected to the block’s input via connection lines (networks);
  • numeric constants entered by the user or selected from the named constant directory;
  • data from controller service memory registers.

Any input or output of a function block can be inverted. This is functionally equivalent to performing the operation “Logical NOT” on input or output data before, respectively, using this data for processing or sending it to the output network.


A line connecting a data source to one or more data recepients is called a network. In the CFD language, the data source is the output of a function block, a constant or an input register. The recepient is an input of another function block or an output register. In the CFD language a network can only have one data source.

In programming language terms, the network is a “variable”, a place where specific data is stored. After a function block calculates its output value, it writes said value into the network as the network value. The function blocks whose inputs are connected to this network read the data stored in the network and use it in their calculations as input values.

An unbroken connection line from one diagram element to another is a network segment. Network segments can have any number of branches(or none at all), the important part is the connection line being unbroken. This means that the networks described above consist of only one segment and can be referred to as anonymous networks.

Alongside anonymous networks, CannyLab has named networks, which are created by assigning a display name to an existing network on the diagram. Named networks are logically unified, meaning that it is possible to separate the network into several visually unrelated segments for easier composition. For example, the two segments of “Tyre pressure, kPa” (on the figure below) represent the same network, and have the same value at each point in time, despite not being visually connected.

Network segments.


In CFD language, all data takes the form of 16-bit non-negative integer numbers in the range of 0 to 65535. The result of an arithmetic operation is always a numeric value from the specified range, and logical operations results are “1” (true) and “0” (false).

During function diagram execution, where necessary, data conversion from Boolean to Numeric data and vice versa is performed automatically using the following rules:

  • When converting a number to a boolean value, 0 is converted to a value of “false”, any number other than 0 is converted to “true”;
  • The boolean values of “false” and “truth” are used as the numbers 0 and 1, respectively, in arithmetic operations;
  • Inversion at the input or output of any block, automatically converts data to its boolean value as per the above rules.
Data transformation.

The results of arithmetic operations are taken modulo 65535. This means that if the operation result exceeds 65,535, then 65536 is automatically deducted from it. And if the result is less than zero, then 65536 is added to the result, creating the final value.

For example:

\[\ 65535 + 1 = 0\]

\[\ 65535 + 2 = 1\]

\[\ 65500 + 122 = 86\]

\[\ 1 – 2 = 65535\]

\[\ 1 – 3 = 65534\]

\[\ 117 – 259 = 65294\]

Controller Resources Management

In order for the function diagram to use the controller’s physical input data, control the physical outputs, receive and transmit data over the data interfaces or even simply manipulate the built-in LED, the diagram and controller resources have to be linked to each other. In other words, they need to communicate somehow.

In CANNY controllers the access to hardware resources from the user application is implemented in the form of data reads and writes from/to specific registers (addresses) reflecting the status of these resources.

Controller resources require a specific order of access. For example, in the simplest possible case of controlling the embedded LED, you just need to send “1” to a particular register to turn it on and “0” to turn it off. But in order to use, say, a universal external channel for relay control, you will need to first initialize it by writing its specific operating mode value into the relevant configuration register. Only then you can control the electric potential on the channel by sending a “1” or “0” to the channel’s output value register.

As an example, the diagram below is used to control railway crossing traffic lights. Notice the three controller resource bindings in the top of the diagram. This diagram is perfectly suitable for uploading into the PLC and controlling actual hardware.

Traffic light control diagram of a railway crossing, after binding to controller resources.

The list of registers of all the resources available to the user of the controller is in the CannyLab controller register directory, which is available to you via the context menu when assigning values to input and output registers in CannyLab.

The configuration of certain controller resources requires the use of special named constants that can be found in the CannyLab named constant list, which is available to you via the context menu when assigning values to constants.

Detailed description of available resources for each controller and their access procedures are available in the respective manuals.